]> gcc.gnu.org Git - gcc.git/commitdiff
json: support std::unique_ptr in array::append and object::set
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 24 Jul 2024 22:07:53 +0000 (18:07 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Wed, 24 Jul 2024 22:07:53 +0000 (18:07 -0400)
This patch uses templates to add overloads of json::array::append and
json::object::set taking std::unique_ptr<T> where T is a subclass of
json::value.

Doing so makes it much easier to track memory ownership and enforce
schema validity when constructing non-trivial JSON; using the wrong
kind of JSON value leads to compile-time errors like the following:

error: cannot convert ‘unique_ptr<sarif_message>’ to ‘unique_ptr<sarif_log>’
  629 |   location_obj->set<sarif_log> ("message", std::move (message_obj));
      |                                            ~~~~~~~~~~^~~~~~~~~~~~~
      |                                                      |
      |                                                      unique_ptr<sarif_message>

No functional change intended.

gcc/ChangeLog:
* diagnostic-format-json.cc: Define INCLUDE_MEMORY.
* diagnostic-format-sarif.cc: Likewise.
* dumpfile.cc: Likewise.
* gcov.cc: Likewise.
* json.cc: Likewise.  Include "make-unique.h".
(selftest::test_formatting): Exercise overloads of
array::append and object::set that use unique_ptr.
* json.h: Require INCLUDE_MEMORY to have been defined.
(json::object::set): Add a template to add a family of overloads
taking a std::unique_ptr<JsonType>
(json::array::append): Likewise.
* optinfo-emit-json.cc: Define INCLUDE_MEMORY.
* optinfo.cc: Likewise.
* timevar.cc: Likewise.
* toplev.cc: Likewise.
* tree-diagnostic-client-data-hooks.cc: Likewise.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/diagnostic-format-json.cc
gcc/diagnostic-format-sarif.cc
gcc/dumpfile.cc
gcc/gcov.cc
gcc/json.cc
gcc/json.h
gcc/optinfo-emit-json.cc
gcc/optinfo.cc
gcc/timevar.cc
gcc/toplev.cc
gcc/tree-diagnostic-client-data-hooks.cc

index 1bf8da663cc24afc7500ed8bf8c2642a70f61afd..55ba39e0c532ed6f0e13fa01c9d6b0f7298de16c 100644 (file)
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "diagnostic.h"
index d6de5806f5ac312cfdd8b87db6e380467277b400..6aba81c6ac9b36ff634288353cca2a0feef75628 100644 (file)
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #define INCLUDE_VECTOR
 #include "system.h"
 #include "coretypes.h"
index 82bd8b06bebf6ccc697afef00a97cf9aee57be9e..6353c0857449eab857d3306b5f2372c287004ff7 100644 (file)
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "options.h"
index 85fdac4368e893ea32449f9266f20ffc1e5c43d1..aa016c658ce048f901b2e3ee8da4e46286fdc34a 100644 (file)
@@ -32,6 +32,7 @@ along with Gcov; see the file COPYING3.  If not see
 
 #include "config.h"
 #define INCLUDE_ALGORITHM
+#define INCLUDE_MEMORY
 #define INCLUDE_VECTOR
 #define INCLUDE_STRING
 #define INCLUDE_MAP
index 86490259dabf086bf8a2c4015dcae41771853f40..275ef486faf1da9831f37476458b92fe22dd5386 100644 (file)
@@ -19,11 +19,13 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "json.h"
 #include "pretty-print.h"
 #include "math.h"
+#include "make-unique.h"
 #include "selftest.h"
 
 using namespace json;
@@ -499,28 +501,31 @@ test_writing_literals ()
   ASSERT_PRINT_EQ (literal (false), true, "false");
 }
 
-/* Verify that nested values are formatted correctly when written.  */
+/* Verify that nested values are formatted correctly when written.
+
+   Also, make use of array::append(std::unique_ptr<value>) and
+   object::set (const char *key, std::unique_ptr<value> v).*/
 
 static void
 test_formatting ()
 {
   object obj;
   object *child = new object;
-  object *grandchild = new object;
+  std::unique_ptr<object> grandchild = ::make_unique<object> ();
 
   obj.set_string ("str", "bar");
   obj.set ("child", child);
   obj.set_integer ("int", 42);
 
-  child->set ("grandchild", grandchild);
-  child->set_integer ("int", 1776);
-
   array *arr = new array;
   for (int i = 0; i < 3; i++)
-    arr->append (new integer_number (i));
+    arr->append (::make_unique<integer_number> (i));
   grandchild->set ("arr", arr);
   grandchild->set_integer ("int", 1066);
 
+  child->set ("grandchild", std::move (grandchild));
+  child->set_integer ("int", 1776);
+
   /* This test relies on json::object writing out key/value pairs
      in key-insertion order.  */
   ASSERT_PRINT_EQ (obj, true,
index d3493a72d52523594de51dc97554e4aa914f09c5..f80a5e82caf34e4c9df63290233f919f3ba0096b 100644 (file)
@@ -21,6 +21,15 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_JSON_H
 #define GCC_JSON_H
 
+/* This header uses std::unique_ptr, but <memory> can't be directly
+   included due to issues with macros.  Hence <memory> must be included
+   from system.h by defining INCLUDE_MEMORY in any source file using
+   json.h.  */
+
+#ifndef INCLUDE_MEMORY
+# error "You must define INCLUDE_MEMORY before including system.h to use make-unique.h"
+#endif
+
 /* Implementation of JSON, a lightweight data-interchange format.
 
    See http://www.json.org/
@@ -101,6 +110,21 @@ class object : public value
   void print (pretty_printer *pp, bool formatted) const final override;
 
   void set (const char *key, value *v);
+
+  /* Set the property KEY of this object, requiring V
+     to be of a specific json::value subclass.
+
+     This can be used to enforce type-checking, making it easier
+     to comply with a schema, e.g.
+       obj->set<some_subclass> ("property_name", value)
+     leading to a compile-time error if VALUE is not of the
+     appropriate subclass.  */
+  template <typename JsonType>
+  void set (const char *key, std::unique_ptr<JsonType> v)
+  {
+    set (key, v.release ());
+  }
+
   value *get (const char *key) const;
 
   void set_string (const char *key, const char *utf8_value);
@@ -132,6 +156,20 @@ class array : public value
   void append (value *v);
   void append_string (const char *utf8_value);
 
+  /* Append V to this array, requiring V
+     to be a specific json::value subclass.
+
+     This can be used to enforce type-checking, making it easier
+     to comply with a schema, e.g.
+       arr->append<some_subclass> (value)
+     leading to a compile-time error if VALUE is not of the
+     appropriate subclass.  */
+  template <typename JsonType>
+  void append (std::unique_ptr<JsonType> v)
+  {
+    append (v.release ());
+  }
+
  private:
   auto_vec<value *> m_elements;
 };
index faae95fc232a06d11ef8acdc9fba45dade71dfef..87a05a72dd3c0750a1e15f806764899133dc57d4 100644 (file)
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 
index 3048581cf0748366dcfaaac385fbd453baf0ce39..7a8256171744f0f4b030d11e4ae0127f334aaecc 100644 (file)
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 
index 36d95336949d71db7427eddb6d356f511b96cd1a..68bcf44864f9e59353351ea28cf2b91e26aa08ae 100644 (file)
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "timevar.h"
index 8933a89bd2811ab92c39605b438b831aee2a29e2..d9e8b34ae7ca32c5cd266a482c71c474fbbcafc5 100644 (file)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
    Error messages and low-level interface to malloc also handled here.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
index 3e8b031e2cc58906c9edc01d543427c5a421bd3d..a2e4a5c97bd5963566c229e9177c348f469ee3ca 100644 (file)
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "version.h"
This page took 0.074083 seconds and 5 git commands to generate.