get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2196537/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2196537,
    "url": "http://patchwork.ozlabs.org/api/patches/2196537/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260214155201.1049644-6-dmalcolm@redhat.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260214155201.1049644-6-dmalcolm@redhat.com>",
    "list_archive_url": null,
    "date": "2026-02-14T15:52:01",
    "name": "[5/5] aarch64: improve diagnostics for bogus JSON tuning inputs [PR124094]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a24828614ec2ecd33d59227cc6b4db548d40d846",
    "submitter": {
        "id": 24465,
        "url": "http://patchwork.ozlabs.org/api/people/24465/?format=api",
        "name": "David Malcolm",
        "email": "dmalcolm@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260214155201.1049644-6-dmalcolm@redhat.com/mbox/",
    "series": [
        {
            "id": 492183,
            "url": "http://patchwork.ozlabs.org/api/series/492183/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=492183",
            "date": "2026-02-14T15:51:56",
            "name": "Improve diagnostics for bad JSON inputs [PR124094]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492183/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196537/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196537/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=AlXpOXyv;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=AlXpOXyv",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "sourceware.org; spf=pass smtp.mailfrom=redhat.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fCtr747gHz1xwj\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 15 Feb 2026 02:53:59 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 71A2E4BAD16A\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 15:53:57 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id 693734BAD167\n for <gcc-patches@gcc.gnu.org>; Sat, 14 Feb 2026 15:52:31 +0000 (GMT)",
            "from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-685-UhVpOTPLPVyzvhL5ZzaneA-1; Sat,\n 14 Feb 2026 10:52:27 -0500",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id A921B1956048; Sat, 14 Feb 2026 15:52:25 +0000 (UTC)",
            "from t14s.localdomain.com (unknown [10.22.88.22])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id ED8F11955D85; Sat, 14 Feb 2026 15:52:22 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 71A2E4BAD16A",
            "OpenDKIM Filter v2.11.0 sourceware.org 693734BAD167"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 693734BAD167",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 693734BAD167",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1771084351; cv=none;\n b=taTi115nDb+0tfXwHIIASVZcfACU8RrDk8MyIRJHeBPt1dK6GPIB8hecvPLhnS+EoN1XbAl408P2kgM1koQAmLvQ/8os+4QV3tk/Tvogjv2wblGKcxF1OE2hRCkeOlEgd/tpSljdaAuU6772BLa9bHzp8ZDMu1L7UuPoM3EdByg=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1771084351; c=relaxed/simple;\n bh=g5LbEWRJuhlR4i5DUH+MNRgjrYRG+tEyCwiL896TQc4=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=q4WcHdsHmEfhlf9jGsLSXTR8v2/LSGA+zp0Cv3pSeUB0v63vGAd2HN4yCMzMxMinbkSEFqHHebeXXPRYfWGrTmjAxNGh38bJeHk4PNbDzOon+KPrHKwvg10EPhOJLa6FIP+BM0GjFN2LPVK8FuxBePPU8OzlDyLjFS0ugdrUADM=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1771084351;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=ryZvUZNXC182mgK5ZVFelfNqDcpoHsXre5hH1yTjVhg=;\n b=AlXpOXyv8y390oocrsY3vzddP7NFox8vPMubHeVPhvH9rf9RNVhnOj7nBgojNC2xmC97jD\n y9LuDjcdnGfmKdIZrUugBJUDu2CFMjWbp2LNjRB1t3EnUEy1Kn1PTmORiSxd62FwWv51by\n t9mtwf7yYvroL9tLI3HcNI/vD2piaHE=",
        "X-MC-Unique": "UhVpOTPLPVyzvhL5ZzaneA-1",
        "X-Mimecast-MFC-AGG-ID": "UhVpOTPLPVyzvhL5ZzaneA_1771084345",
        "From": "David Malcolm <dmalcolm@redhat.com>",
        "To": "gcc-patches@gcc.gnu.org, Yangyu Chen <cyy@cyyself.name>,\n Soumya AR <soumyaa@nvidia.com>, jakub@redhat.com,\n Richard Biener <richard.guenther@gmail.com>",
        "Cc": "Alfie Richards <alfie.richards@arm.com>,\n Sandra Loosemore <sloosemore@baylibre.com>,\n Martin Liska <martin.liska@hey.com>,\n Evgeny Stupachenko <evstupac@gmail.com>,\n Alice Carlotti <alice.carlotti@arm.com>,\n Jeff Law <jeffrey.law@oss.qualcomm.com>,\n Jerry DeLisle <jvdelisle@gcc.gnu.org>, Harald Anlauf <anlauf@gmx.de>,\n Paul Thomas <pault@gcc.gnu.org>,\n Richard Sandiford <rdsandiford@googlemail.com>,\n Joseph Myers <josmyers@redhat.com>, Jason Merrill <jason@redhat.com>,\n David Malcolm <dmalcolm@redhat.com>",
        "Subject": "[PATCH 5/5] aarch64: improve diagnostics for bogus JSON tuning inputs\n [PR124094]",
        "Date": "Sat, 14 Feb 2026 10:52:01 -0500",
        "Message-ID": "<20260214155201.1049644-6-dmalcolm@redhat.com>",
        "In-Reply-To": "<20260214155201.1049644-1-dmalcolm@redhat.com>",
        "References": "<tencent_048DF6A8630E2E590C79C840A31F1FA86006@qq.com>\n <20260214155201.1049644-1-dmalcolm@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "ivHk_9NcxCxBRIfIJow6AGWCeuO1zDl85CMQVhG0NOs_1771084345",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "Use json-diagnostic.{h,cc} to improve the diagnostics issued\nfor malformed and invalid JSON tuning inputs: report the\nfile/line/column and, if possible, the JSON Pointer of the\nproblematic input.\n\nBefore\n------\n\n$ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json\ncc1: error: error parsing JSON data: expected ':'; got number\n\n$ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json\ncc1: warning: JSON tuning file does not contain version information; compatibility cannot be verified\ncc1: error: key ‘tune_params.sve_width’ value 5000000000 is out of range for ‘uint’ type [0, 4294967295]\ncc1: error: validation failed for the provided JSON data\n\nAfter\n-----\n\n$ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json\nmalformed.json:3:17: error: error parsing JSON data: expected ':'; got number\n    3 |     \"sve_width\" 128\n      |                 ^~~\n\n$ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json\ncc1: warning: JSON tuning file does not contain version information; compatibility cannot be verified\nunsigned-3.json: In JSON value ‘/tune_params/sve_width’\nunsigned-3.json:3:18: error: key ‘tune_params.sve_width’ value 5000000000 is out of range for ‘uint’ type [0, 4294967295]\n    3 |     \"sve_width\": 5000000000\n      |                  ^~~~~~~~~~\ncc1: error: validation failed for the provided JSON data\n\ngcc/ChangeLog:\n\tPR target/124094\n\t* config/aarch64/aarch64-generate-json-tuning-routines.py\n\t(generate_field_code): Add \"ctxt, \" arg to function call when\n\toperation is \"parse\".\n\t(generate_function): Add \"gcc_json_context &ctxt, \" param to\n\tfunction decl when operation is \"parse\".\n\t* config/aarch64/aarch64-json-tunings-parser-generated.inc:\n\tRegenerate, passing around a gcc_json_context &.\n\t* config/aarch64/aarch64-json-tunings-parser.cc: Include\n\t\"json-diagnostic.h\".\n\t(WARNING_OPT) New macro.\n\t(PARSE_INTEGER_FIELD): Add \"ctxt\" param and pass it around.\n\t(PARSE_UNSIGNED_INTEGER_FIELD): Likewise.\n\t(PARSE_BOOLEAN_FIELD): Likewise.\n\t(PARSE_STRING_FIELD): Likewise.\n\t(PARSE_OBJECT): Likewise.\n\t(PARSE_ARRAY_FIELD): Likewise.\n\t(PARSE_ENUM_FIELD): Likewise.\n\t(parse_func_type): Likewise.\n\t(parse_object_helper): Likewise.  Use json_error rather than error.\n\t(inform_about_wrong_kind_of_json_value): New.\n\t(extract_string): Add \"ctxt\" param.  Replace \"warning\" with a pair\n\tof calls to json_warning and\n\tinform_about_wrong_kind_of_json_value, tweaking wording\n\taccordingly.\n\t(extract_integer): Likewise.\n\t(extract_unsigned_integer): Likewise.\n\t(parse_enum_field): Likewise.\n\t(validate_and_traverse): Replace \"warning\" and \"error\" with\n\t\"json_warning\" and \"json_error\".\n\t(check_version_compatibility): Use WARNING_OPT.  Add\n\tauto_diagnostic_group to group the error and note.\n\t(aarch64_load_tuning_params_from_json_string): Add \"js_filename\"\n\tparam.  Use gcc_json_context to capture location info.  Use it\n\twhen reporting errors to get file/line/column info.  Replace check\n\ton root being non-null with assertion, as this is guaranteed if\n\terror is non-null.  Replace warning with json_warning.\n\t(aarch64_load_tuning_params_from_json): Pass data_filename to\n\taarch64_load_tuning_params_from_json_string for use when reporting\n\tdiagnostics.\n\t(selftest::test_json_integers): Add a placeholder filename.\n\t(selftest::test_json_boolean): Likewise.\n\t(selftest::test_json_strings): Likewise.\n\t(selftest::test_json_enums): Likewise.\n\ngcc/testsuite/ChangeLog:\n\tPR target/124094\n\t* gcc.target/aarch64/aarch64-json-tunings/boolean-2.c: Add options\n\t-fdiagnostics-show-caret -fdiagnostics-show-line-numbers.  Replace\n\tdg-error with a pair of dg-regexps to verify that we report the\n\tfilename and JSON Pointer of where the error occurs, and then\n\tthe filename and location within the JSON file.  Verify that we\n\tquote and underline the pertinent part of the JSON file.\n\t* gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/enum-2.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/integer-2.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/integer-3.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/string-2.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c: Likewise.\n\t* gcc.target/aarch64/aarch64-json-tunings/malformed.c: New test,\n\tto verify behavior on a malformed JSON input file.\n\t* gcc.target/aarch64/aarch64-json-tunings/malformed.json: New\n\ttest file.  This is malformed JSON, due to a missing ':\" between\n\tkey and value.\n\nSigned-off-by: David Malcolm <dmalcolm@redhat.com>\n---\n .../aarch64-generate-json-tuning-routines.py  |  17 +-\n .../aarch64-json-tunings-parser-generated.inc | 428 +++++++++---------\n .../aarch64/aarch64-json-tunings-parser.cc    | 276 +++++++----\n .../aarch64/aarch64-json-tunings/boolean-2.c  |  12 +-\n .../aarch64-json-tunings/empty-brackets.c     |   9 +-\n .../aarch64/aarch64-json-tunings/enum-2.c     |  19 +-\n .../aarch64/aarch64-json-tunings/integer-2.c  |  14 +-\n .../aarch64/aarch64-json-tunings/integer-3.c  |  13 +-\n .../aarch64/aarch64-json-tunings/malformed.c  |  11 +\n .../aarch64-json-tunings/malformed.json       |   5 +\n .../aarch64/aarch64-json-tunings/string-2.c   |  12 +-\n .../aarch64-json-tunings/unidentified-key.c   |  12 +-\n .../aarch64/aarch64-json-tunings/unsigned-2.c |  10 +-\n .../aarch64/aarch64-json-tunings/unsigned-3.c |  10 +-\n 14 files changed, 517 insertions(+), 331 deletions(-)\n create mode 100644 gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json",
    "diff": "diff --git a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py\nindex a4f9e4ece71a3..9253cf58cdfa1 100755\n--- a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py\n+++ b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py\n@@ -85,15 +85,20 @@ def generate_field_code(\n ) -> List[str]:\n     lines = []\n \n+    if operation == 'parse':\n+        ctxt = 'ctxt, '\n+    else:\n+        ctxt = ''\n+\n     if isinstance(value, str):\n         macro = get_macro(operation.upper(), value)\n         if value == \"enum\":\n             enum_mapping = f\"{key}_mappings\"\n             lines.append(\n-                f'{indent}{macro} ({obj_name}, \"{key}\", {struct_name}.{key}, {enum_mapping});'\n+                f'{indent}{macro} ({ctxt}{obj_name}, \"{key}\", {struct_name}.{key}, {enum_mapping});'\n             )\n         else:\n-            lines.append(f'{indent}{macro} ({obj_name}, \"{key}\", {struct_name}.{key});')\n+            lines.append(f'{indent}{macro} ({ctxt}{obj_name}, \"{key}\", {struct_name}.{key});')\n \n     elif isinstance(value, dict):\n         # Nested object - find function name based on current context + key\n@@ -102,7 +107,7 @@ def generate_field_code(\n         func_name = function_map.get(child_path_key, f\"{operation.lower()}_{key}\")\n         macro_name = f\"{operation.upper()}_OBJECT\"\n         lines.append(\n-            f'{indent}{macro_name} ({obj_name}, \"{key}\", {struct_name}.{key}, {func_name});'\n+            f'{indent}{macro_name} ({ctxt}{obj_name}, \"{key}\", {struct_name}.{key}, {func_name});'\n         )\n \n     elif isinstance(value, list) and len(value) > 0:\n@@ -117,11 +122,11 @@ def generate_field_code(\n \n             if operation.lower() == \"serialize\":\n                 lines.append(\n-                    f'{indent}{macro_name} ({obj_name}, \"{key}\", {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'\n+                    f'{indent}{macro_name} ({ctxt}{obj_name}, \"{key}\", {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'\n                 )\n             else:\n                 lines.append(\n-                    f'{indent}{macro_name} ({obj_name}, \"{key}\", {struct_name}.{key}, {func_name});'\n+                    f'{indent}{macro_name} ({ctxt}{obj_name}, \"{key}\", {struct_name}.{key}, {func_name});'\n                 )\n         else:\n             raise ValueError(f\"Arrays of non-object types are not yet supported: {key}\")\n@@ -175,7 +180,7 @@ def generate_function(\n \n     if operation.lower() == \"parse\":\n         lines.append(\"static void\")\n-        lines.append(f\"parse_{full_name} (const json::object *jo, T &{local_name})\")\n+        lines.append(f\"parse_{full_name} (gcc_json_context &ctxt, const json::object &jo, T &{local_name})\")\n         lines.append(\"{\")\n \n         for key, value in schema.items():\ndiff --git a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc\nindex 882d8f799755a..3908a4f1a3114 100644\n--- a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc\n+++ b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc\n@@ -38,319 +38,319 @@ static const enum_mapping<aarch64_ldp_stp_policy> stp_policy_model_mappings[] =\n \n template <typename T>\n static void\n-parse_insn_extra_cost_alu (const json::object *jo, T &alu)\n+parse_insn_extra_cost_alu (gcc_json_context &ctxt, const json::object &jo, T &alu)\n {\n-  PARSE_INTEGER_FIELD (jo, \"arith\", alu.arith);\n-  PARSE_INTEGER_FIELD (jo, \"logical\", alu.logical);\n-  PARSE_INTEGER_FIELD (jo, \"shift\", alu.shift);\n-  PARSE_INTEGER_FIELD (jo, \"shift_reg\", alu.shift_reg);\n-  PARSE_INTEGER_FIELD (jo, \"arith_shift\", alu.arith_shift);\n-  PARSE_INTEGER_FIELD (jo, \"arith_shift_reg\", alu.arith_shift_reg);\n-  PARSE_INTEGER_FIELD (jo, \"log_shift\", alu.log_shift);\n-  PARSE_INTEGER_FIELD (jo, \"log_shift_reg\", alu.log_shift_reg);\n-  PARSE_INTEGER_FIELD (jo, \"extend\", alu.extend);\n-  PARSE_INTEGER_FIELD (jo, \"extend_arith\", alu.extend_arith);\n-  PARSE_INTEGER_FIELD (jo, \"bfi\", alu.bfi);\n-  PARSE_INTEGER_FIELD (jo, \"bfx\", alu.bfx);\n-  PARSE_INTEGER_FIELD (jo, \"clz\", alu.clz);\n-  PARSE_INTEGER_FIELD (jo, \"rev\", alu.rev);\n-  PARSE_INTEGER_FIELD (jo, \"non_exec\", alu.non_exec);\n-  PARSE_BOOLEAN_FIELD (jo, \"non_exec_costs_exec\", alu.non_exec_costs_exec);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"arith\", alu.arith);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"logical\", alu.logical);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"shift\", alu.shift);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"shift_reg\", alu.shift_reg);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"arith_shift\", alu.arith_shift);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"arith_shift_reg\", alu.arith_shift_reg);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"log_shift\", alu.log_shift);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"log_shift_reg\", alu.log_shift_reg);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"extend\", alu.extend);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"extend_arith\", alu.extend_arith);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"bfi\", alu.bfi);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"bfx\", alu.bfx);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"clz\", alu.clz);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"rev\", alu.rev);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"non_exec\", alu.non_exec);\n+  PARSE_BOOLEAN_FIELD (ctxt, jo, \"non_exec_costs_exec\", alu.non_exec_costs_exec);\n }\n \n template <typename T>\n static void\n-parse_insn_extra_cost_mult_element (const json::object *jo, T &mult_element)\n+parse_insn_extra_cost_mult_element (gcc_json_context &ctxt, const json::object &jo, T &mult_element)\n {\n-  PARSE_INTEGER_FIELD (jo, \"simple\", mult_element.simple);\n-  PARSE_INTEGER_FIELD (jo, \"flag_setting\", mult_element.flag_setting);\n-  PARSE_INTEGER_FIELD (jo, \"extend\", mult_element.extend);\n-  PARSE_INTEGER_FIELD (jo, \"add\", mult_element.add);\n-  PARSE_INTEGER_FIELD (jo, \"extend_add\", mult_element.extend_add);\n-  PARSE_INTEGER_FIELD (jo, \"idiv\", mult_element.idiv);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"simple\", mult_element.simple);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"flag_setting\", mult_element.flag_setting);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"extend\", mult_element.extend);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"add\", mult_element.add);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"extend_add\", mult_element.extend_add);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"idiv\", mult_element.idiv);\n }\n \n template <typename T>\n static void\n-parse_insn_extra_cost_ldst (const json::object *jo, T &ldst)\n+parse_insn_extra_cost_ldst (gcc_json_context &ctxt, const json::object &jo, T &ldst)\n {\n-  PARSE_INTEGER_FIELD (jo, \"load\", ldst.load);\n-  PARSE_INTEGER_FIELD (jo, \"load_sign_extend\", ldst.load_sign_extend);\n-  PARSE_INTEGER_FIELD (jo, \"ldrd\", ldst.ldrd);\n-  PARSE_INTEGER_FIELD (jo, \"ldm_1st\", ldst.ldm_1st);\n-  PARSE_INTEGER_FIELD (jo, \"ldm_regs_per_insn_1st\", ldst.ldm_regs_per_insn_1st);\n-  PARSE_INTEGER_FIELD (jo, \"ldm_regs_per_insn_subsequent\", ldst.ldm_regs_per_insn_subsequent);\n-  PARSE_INTEGER_FIELD (jo, \"loadf\", ldst.loadf);\n-  PARSE_INTEGER_FIELD (jo, \"loadd\", ldst.loadd);\n-  PARSE_INTEGER_FIELD (jo, \"load_unaligned\", ldst.load_unaligned);\n-  PARSE_INTEGER_FIELD (jo, \"store\", ldst.store);\n-  PARSE_INTEGER_FIELD (jo, \"strd\", ldst.strd);\n-  PARSE_INTEGER_FIELD (jo, \"stm_1st\", ldst.stm_1st);\n-  PARSE_INTEGER_FIELD (jo, \"stm_regs_per_insn_1st\", ldst.stm_regs_per_insn_1st);\n-  PARSE_INTEGER_FIELD (jo, \"stm_regs_per_insn_subsequent\", ldst.stm_regs_per_insn_subsequent);\n-  PARSE_INTEGER_FIELD (jo, \"storef\", ldst.storef);\n-  PARSE_INTEGER_FIELD (jo, \"stored\", ldst.stored);\n-  PARSE_INTEGER_FIELD (jo, \"store_unaligned\", ldst.store_unaligned);\n-  PARSE_INTEGER_FIELD (jo, \"loadv\", ldst.loadv);\n-  PARSE_INTEGER_FIELD (jo, \"storev\", ldst.storev);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load\", ldst.load);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load_sign_extend\", ldst.load_sign_extend);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ldrd\", ldst.ldrd);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ldm_1st\", ldst.ldm_1st);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ldm_regs_per_insn_1st\", ldst.ldm_regs_per_insn_1st);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ldm_regs_per_insn_subsequent\", ldst.ldm_regs_per_insn_subsequent);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"loadf\", ldst.loadf);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"loadd\", ldst.loadd);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load_unaligned\", ldst.load_unaligned);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store\", ldst.store);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"strd\", ldst.strd);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"stm_1st\", ldst.stm_1st);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"stm_regs_per_insn_1st\", ldst.stm_regs_per_insn_1st);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"stm_regs_per_insn_subsequent\", ldst.stm_regs_per_insn_subsequent);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"storef\", ldst.storef);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"stored\", ldst.stored);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_unaligned\", ldst.store_unaligned);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"loadv\", ldst.loadv);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"storev\", ldst.storev);\n }\n \n template <typename T>\n static void\n-parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element)\n+parse_insn_extra_cost_fp_element (gcc_json_context &ctxt, const json::object &jo, T &fp_element)\n {\n-  PARSE_INTEGER_FIELD (jo, \"div\", fp_element.div);\n-  PARSE_INTEGER_FIELD (jo, \"mult\", fp_element.mult);\n-  PARSE_INTEGER_FIELD (jo, \"mult_addsub\", fp_element.mult_addsub);\n-  PARSE_INTEGER_FIELD (jo, \"fma\", fp_element.fma);\n-  PARSE_INTEGER_FIELD (jo, \"addsub\", fp_element.addsub);\n-  PARSE_INTEGER_FIELD (jo, \"fpconst\", fp_element.fpconst);\n-  PARSE_INTEGER_FIELD (jo, \"neg\", fp_element.neg);\n-  PARSE_INTEGER_FIELD (jo, \"compare\", fp_element.compare);\n-  PARSE_INTEGER_FIELD (jo, \"widen\", fp_element.widen);\n-  PARSE_INTEGER_FIELD (jo, \"narrow\", fp_element.narrow);\n-  PARSE_INTEGER_FIELD (jo, \"toint\", fp_element.toint);\n-  PARSE_INTEGER_FIELD (jo, \"fromint\", fp_element.fromint);\n-  PARSE_INTEGER_FIELD (jo, \"roundint\", fp_element.roundint);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"div\", fp_element.div);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"mult\", fp_element.mult);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"mult_addsub\", fp_element.mult_addsub);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fma\", fp_element.fma);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"addsub\", fp_element.addsub);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fpconst\", fp_element.fpconst);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"neg\", fp_element.neg);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"compare\", fp_element.compare);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"widen\", fp_element.widen);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"narrow\", fp_element.narrow);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"toint\", fp_element.toint);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fromint\", fp_element.fromint);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"roundint\", fp_element.roundint);\n }\n \n template <typename T>\n static void\n-parse_insn_extra_cost_vect (const json::object *jo, T &vect)\n+parse_insn_extra_cost_vect (gcc_json_context &ctxt, const json::object &jo, T &vect)\n {\n-  PARSE_INTEGER_FIELD (jo, \"alu\", vect.alu);\n-  PARSE_INTEGER_FIELD (jo, \"mult\", vect.mult);\n-  PARSE_INTEGER_FIELD (jo, \"movi\", vect.movi);\n-  PARSE_INTEGER_FIELD (jo, \"dup\", vect.dup);\n-  PARSE_INTEGER_FIELD (jo, \"extract\", vect.extract);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"alu\", vect.alu);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"mult\", vect.mult);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"movi\", vect.movi);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"dup\", vect.dup);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"extract\", vect.extract);\n }\n \n template <typename T>\n static void\n-parse_addr_cost_addr_scale_costs (const json::object *jo, T &addr_scale_costs)\n+parse_addr_cost_addr_scale_costs (gcc_json_context &ctxt, const json::object &jo, T &addr_scale_costs)\n {\n-  PARSE_INTEGER_FIELD (jo, \"hi\", addr_scale_costs.hi);\n-  PARSE_INTEGER_FIELD (jo, \"si\", addr_scale_costs.si);\n-  PARSE_INTEGER_FIELD (jo, \"di\", addr_scale_costs.di);\n-  PARSE_INTEGER_FIELD (jo, \"ti\", addr_scale_costs.ti);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"hi\", addr_scale_costs.hi);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"si\", addr_scale_costs.si);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"di\", addr_scale_costs.di);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ti\", addr_scale_costs.ti);\n }\n \n template <typename T>\n static void\n-parse_regmove_cost (const json::object *jo, T &regmove_cost)\n+parse_regmove_cost (gcc_json_context &ctxt, const json::object &jo, T &regmove_cost)\n {\n-  PARSE_INTEGER_FIELD (jo, \"GP2GP\", regmove_cost.GP2GP);\n-  PARSE_INTEGER_FIELD (jo, \"GP2FP\", regmove_cost.GP2FP);\n-  PARSE_INTEGER_FIELD (jo, \"FP2GP\", regmove_cost.FP2GP);\n-  PARSE_INTEGER_FIELD (jo, \"FP2FP\", regmove_cost.FP2FP);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"GP2GP\", regmove_cost.GP2GP);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"GP2FP\", regmove_cost.GP2FP);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"FP2GP\", regmove_cost.FP2GP);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"FP2FP\", regmove_cost.FP2FP);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_advsimd (const json::object *jo, T &advsimd)\n+parse_vec_costs_advsimd (gcc_json_context &ctxt, const json::object &jo, T &advsimd)\n {\n-  PARSE_INTEGER_FIELD (jo, \"int_stmt_cost\", advsimd.int_stmt_cost);\n-  PARSE_INTEGER_FIELD (jo, \"fp_stmt_cost\", advsimd.fp_stmt_cost);\n-  PARSE_INTEGER_FIELD (jo, \"ld2_st2_permute_cost\", advsimd.ld2_st2_permute_cost);\n-  PARSE_INTEGER_FIELD (jo, \"ld3_st3_permute_cost\", advsimd.ld3_st3_permute_cost);\n-  PARSE_INTEGER_FIELD (jo, \"ld4_st4_permute_cost\", advsimd.ld4_st4_permute_cost);\n-  PARSE_INTEGER_FIELD (jo, \"permute_cost\", advsimd.permute_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_i8_cost\", advsimd.reduc_i8_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_i16_cost\", advsimd.reduc_i16_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_i32_cost\", advsimd.reduc_i32_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_i64_cost\", advsimd.reduc_i64_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_f16_cost\", advsimd.reduc_f16_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_f32_cost\", advsimd.reduc_f32_cost);\n-  PARSE_INTEGER_FIELD (jo, \"reduc_f64_cost\", advsimd.reduc_f64_cost);\n-  PARSE_INTEGER_FIELD (jo, \"store_elt_extra_cost\", advsimd.store_elt_extra_cost);\n-  PARSE_INTEGER_FIELD (jo, \"vec_to_scalar_cost\", advsimd.vec_to_scalar_cost);\n-  PARSE_INTEGER_FIELD (jo, \"scalar_to_vec_cost\", advsimd.scalar_to_vec_cost);\n-  PARSE_INTEGER_FIELD (jo, \"align_load_cost\", advsimd.align_load_cost);\n-  PARSE_INTEGER_FIELD (jo, \"unalign_load_cost\", advsimd.unalign_load_cost);\n-  PARSE_INTEGER_FIELD (jo, \"unalign_store_cost\", advsimd.unalign_store_cost);\n-  PARSE_INTEGER_FIELD (jo, \"store_cost\", advsimd.store_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"int_stmt_cost\", advsimd.int_stmt_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fp_stmt_cost\", advsimd.fp_stmt_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ld2_st2_permute_cost\", advsimd.ld2_st2_permute_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ld3_st3_permute_cost\", advsimd.ld3_st3_permute_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"ld4_st4_permute_cost\", advsimd.ld4_st4_permute_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"permute_cost\", advsimd.permute_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_i8_cost\", advsimd.reduc_i8_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_i16_cost\", advsimd.reduc_i16_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_i32_cost\", advsimd.reduc_i32_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_i64_cost\", advsimd.reduc_i64_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_f16_cost\", advsimd.reduc_f16_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_f32_cost\", advsimd.reduc_f32_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"reduc_f64_cost\", advsimd.reduc_f64_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_elt_extra_cost\", advsimd.store_elt_extra_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"vec_to_scalar_cost\", advsimd.vec_to_scalar_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scalar_to_vec_cost\", advsimd.scalar_to_vec_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"align_load_cost\", advsimd.align_load_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"unalign_load_cost\", advsimd.unalign_load_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"unalign_store_cost\", advsimd.unalign_store_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_cost\", advsimd.store_cost);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_sve (const json::object *jo, T &sve)\n+parse_vec_costs_sve (gcc_json_context &ctxt, const json::object &jo, T &sve)\n {\n-  PARSE_INTEGER_FIELD (jo, \"clast_cost\", sve.clast_cost);\n-  PARSE_INTEGER_FIELD (jo, \"fadda_f16_cost\", sve.fadda_f16_cost);\n-  PARSE_INTEGER_FIELD (jo, \"fadda_f32_cost\", sve.fadda_f32_cost);\n-  PARSE_INTEGER_FIELD (jo, \"fadda_f64_cost\", sve.fadda_f64_cost);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"gather_load_x32_cost\", sve.gather_load_x32_cost);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"gather_load_x64_cost\", sve.gather_load_x64_cost);\n-  PARSE_INTEGER_FIELD (jo, \"gather_load_x32_init_cost\", sve.gather_load_x32_init_cost);\n-  PARSE_INTEGER_FIELD (jo, \"gather_load_x64_init_cost\", sve.gather_load_x64_init_cost);\n-  PARSE_INTEGER_FIELD (jo, \"scatter_store_elt_cost\", sve.scatter_store_elt_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"clast_cost\", sve.clast_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fadda_f16_cost\", sve.fadda_f16_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fadda_f32_cost\", sve.fadda_f32_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fadda_f64_cost\", sve.fadda_f64_cost);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"gather_load_x32_cost\", sve.gather_load_x32_cost);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"gather_load_x64_cost\", sve.gather_load_x64_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"gather_load_x32_init_cost\", sve.gather_load_x32_init_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"gather_load_x64_init_cost\", sve.gather_load_x64_init_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scatter_store_elt_cost\", sve.scatter_store_elt_cost);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_issue_info_scalar (const json::object *jo, T &scalar)\n+parse_vec_costs_issue_info_scalar (gcc_json_context &ctxt, const json::object &jo, T &scalar)\n {\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"loads_stores_per_cycle\", scalar.loads_stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"stores_per_cycle\", scalar.stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"general_ops_per_cycle\", scalar.general_ops_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_load_general_ops\", scalar.fp_simd_load_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_store_general_ops\", scalar.fp_simd_store_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"loads_stores_per_cycle\", scalar.loads_stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"stores_per_cycle\", scalar.stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"general_ops_per_cycle\", scalar.general_ops_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_load_general_ops\", scalar.fp_simd_load_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_store_general_ops\", scalar.fp_simd_store_general_ops);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_issue_info_advsimd (const json::object *jo, T &advsimd)\n+parse_vec_costs_issue_info_advsimd (gcc_json_context &ctxt, const json::object &jo, T &advsimd)\n {\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"loads_stores_per_cycle\", advsimd.loads_stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"stores_per_cycle\", advsimd.stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"general_ops_per_cycle\", advsimd.general_ops_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_load_general_ops\", advsimd.fp_simd_load_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_store_general_ops\", advsimd.fp_simd_store_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld2_st2_general_ops\", advsimd.ld2_st2_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld3_st3_general_ops\", advsimd.ld3_st3_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld4_st4_general_ops\", advsimd.ld4_st4_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"loads_stores_per_cycle\", advsimd.loads_stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"stores_per_cycle\", advsimd.stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"general_ops_per_cycle\", advsimd.general_ops_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_load_general_ops\", advsimd.fp_simd_load_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_store_general_ops\", advsimd.fp_simd_store_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld2_st2_general_ops\", advsimd.ld2_st2_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld3_st3_general_ops\", advsimd.ld3_st3_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld4_st4_general_ops\", advsimd.ld4_st4_general_ops);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_issue_info_sve (const json::object *jo, T &sve)\n+parse_vec_costs_issue_info_sve (gcc_json_context &ctxt, const json::object &jo, T &sve)\n {\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"loads_stores_per_cycle\", sve.loads_stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"stores_per_cycle\", sve.stores_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"general_ops_per_cycle\", sve.general_ops_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_load_general_ops\", sve.fp_simd_load_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_simd_store_general_ops\", sve.fp_simd_store_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld2_st2_general_ops\", sve.ld2_st2_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld3_st3_general_ops\", sve.ld3_st3_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"ld4_st4_general_ops\", sve.ld4_st4_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"pred_ops_per_cycle\", sve.pred_ops_per_cycle);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"while_pred_ops\", sve.while_pred_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"int_cmp_pred_ops\", sve.int_cmp_pred_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fp_cmp_pred_ops\", sve.fp_cmp_pred_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"gather_scatter_pair_general_ops\", sve.gather_scatter_pair_general_ops);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"gather_scatter_pair_pred_ops\", sve.gather_scatter_pair_pred_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"loads_stores_per_cycle\", sve.loads_stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"stores_per_cycle\", sve.stores_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"general_ops_per_cycle\", sve.general_ops_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_load_general_ops\", sve.fp_simd_load_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_simd_store_general_ops\", sve.fp_simd_store_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld2_st2_general_ops\", sve.ld2_st2_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld3_st3_general_ops\", sve.ld3_st3_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"ld4_st4_general_ops\", sve.ld4_st4_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"pred_ops_per_cycle\", sve.pred_ops_per_cycle);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"while_pred_ops\", sve.while_pred_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"int_cmp_pred_ops\", sve.int_cmp_pred_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fp_cmp_pred_ops\", sve.fp_cmp_pred_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"gather_scatter_pair_general_ops\", sve.gather_scatter_pair_general_ops);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"gather_scatter_pair_pred_ops\", sve.gather_scatter_pair_pred_ops);\n }\n \n template <typename T>\n static void\n-parse_branch_costs (const json::object *jo, T &branch_costs)\n+parse_branch_costs (gcc_json_context &ctxt, const json::object &jo, T &branch_costs)\n {\n-  PARSE_INTEGER_FIELD (jo, \"predictable\", branch_costs.predictable);\n-  PARSE_INTEGER_FIELD (jo, \"unpredictable\", branch_costs.unpredictable);\n-  PARSE_INTEGER_FIELD (jo, \"br_mispredict_factor\", branch_costs.br_mispredict_factor);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"predictable\", branch_costs.predictable);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"unpredictable\", branch_costs.unpredictable);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"br_mispredict_factor\", branch_costs.br_mispredict_factor);\n }\n \n template <typename T>\n static void\n-parse_approx_modes (const json::object *jo, T &approx_modes)\n+parse_approx_modes (gcc_json_context &ctxt, const json::object &jo, T &approx_modes)\n {\n-  PARSE_INTEGER_FIELD (jo, \"division\", approx_modes.division);\n-  PARSE_INTEGER_FIELD (jo, \"sqrt\", approx_modes.sqrt);\n-  PARSE_INTEGER_FIELD (jo, \"recip_sqrt\", approx_modes.recip_sqrt);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"division\", approx_modes.division);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"sqrt\", approx_modes.sqrt);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"recip_sqrt\", approx_modes.recip_sqrt);\n }\n \n template <typename T>\n static void\n-parse_memmov_cost (const json::object *jo, T &memmov_cost)\n+parse_memmov_cost (gcc_json_context &ctxt, const json::object &jo, T &memmov_cost)\n {\n-  PARSE_INTEGER_FIELD (jo, \"load_int\", memmov_cost.load_int);\n-  PARSE_INTEGER_FIELD (jo, \"store_int\", memmov_cost.store_int);\n-  PARSE_INTEGER_FIELD (jo, \"load_fp\", memmov_cost.load_fp);\n-  PARSE_INTEGER_FIELD (jo, \"store_fp\", memmov_cost.store_fp);\n-  PARSE_INTEGER_FIELD (jo, \"load_pred\", memmov_cost.load_pred);\n-  PARSE_INTEGER_FIELD (jo, \"store_pred\", memmov_cost.store_pred);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load_int\", memmov_cost.load_int);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_int\", memmov_cost.store_int);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load_fp\", memmov_cost.load_fp);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_fp\", memmov_cost.store_fp);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"load_pred\", memmov_cost.load_pred);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"store_pred\", memmov_cost.store_pred);\n }\n \n template <typename T>\n static void\n-parse_prefetch (const json::object *jo, T &prefetch)\n+parse_prefetch (gcc_json_context &ctxt, const json::object &jo, T &prefetch)\n {\n-  PARSE_INTEGER_FIELD (jo, \"num_slots\", prefetch.num_slots);\n-  PARSE_INTEGER_FIELD (jo, \"l1_cache_size\", prefetch.l1_cache_size);\n-  PARSE_INTEGER_FIELD (jo, \"l1_cache_line_size\", prefetch.l1_cache_line_size);\n-  PARSE_INTEGER_FIELD (jo, \"l2_cache_size\", prefetch.l2_cache_size);\n-  PARSE_BOOLEAN_FIELD (jo, \"prefetch_dynamic_strides\", prefetch.prefetch_dynamic_strides);\n-  PARSE_INTEGER_FIELD (jo, \"minimum_stride\", prefetch.minimum_stride);\n-  PARSE_INTEGER_FIELD (jo, \"default_opt_level\", prefetch.default_opt_level);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"num_slots\", prefetch.num_slots);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"l1_cache_size\", prefetch.l1_cache_size);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"l1_cache_line_size\", prefetch.l1_cache_line_size);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"l2_cache_size\", prefetch.l2_cache_size);\n+  PARSE_BOOLEAN_FIELD (ctxt, jo, \"prefetch_dynamic_strides\", prefetch.prefetch_dynamic_strides);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"minimum_stride\", prefetch.minimum_stride);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"default_opt_level\", prefetch.default_opt_level);\n }\n \n template <typename T>\n static void\n-parse_insn_extra_cost (const json::object *jo, T &insn_extra_cost)\n+parse_insn_extra_cost (gcc_json_context &ctxt, const json::object &jo, T &insn_extra_cost)\n {\n-  PARSE_OBJECT (jo, \"alu\", insn_extra_cost.alu, parse_insn_extra_cost_alu);\n-  PARSE_ARRAY_FIELD (jo, \"mult\", insn_extra_cost.mult, parse_insn_extra_cost_mult_element);\n-  PARSE_OBJECT (jo, \"ldst\", insn_extra_cost.ldst, parse_insn_extra_cost_ldst);\n-  PARSE_ARRAY_FIELD (jo, \"fp\", insn_extra_cost.fp, parse_insn_extra_cost_fp_element);\n-  PARSE_OBJECT (jo, \"vect\", insn_extra_cost.vect, parse_insn_extra_cost_vect);\n+  PARSE_OBJECT (ctxt, jo, \"alu\", insn_extra_cost.alu, parse_insn_extra_cost_alu);\n+  PARSE_ARRAY_FIELD (ctxt, jo, \"mult\", insn_extra_cost.mult, parse_insn_extra_cost_mult_element);\n+  PARSE_OBJECT (ctxt, jo, \"ldst\", insn_extra_cost.ldst, parse_insn_extra_cost_ldst);\n+  PARSE_ARRAY_FIELD (ctxt, jo, \"fp\", insn_extra_cost.fp, parse_insn_extra_cost_fp_element);\n+  PARSE_OBJECT (ctxt, jo, \"vect\", insn_extra_cost.vect, parse_insn_extra_cost_vect);\n }\n \n template <typename T>\n static void\n-parse_addr_cost (const json::object *jo, T &addr_cost)\n+parse_addr_cost (gcc_json_context &ctxt, const json::object &jo, T &addr_cost)\n {\n-  PARSE_OBJECT (jo, \"addr_scale_costs\", addr_cost.addr_scale_costs, parse_addr_cost_addr_scale_costs);\n-  PARSE_INTEGER_FIELD (jo, \"pre_modify\", addr_cost.pre_modify);\n-  PARSE_INTEGER_FIELD (jo, \"post_modify\", addr_cost.post_modify);\n-  PARSE_INTEGER_FIELD (jo, \"post_modify_ld3_st3\", addr_cost.post_modify_ld3_st3);\n-  PARSE_INTEGER_FIELD (jo, \"post_modify_ld4_st4\", addr_cost.post_modify_ld4_st4);\n-  PARSE_INTEGER_FIELD (jo, \"register_offset\", addr_cost.register_offset);\n-  PARSE_INTEGER_FIELD (jo, \"register_sextend\", addr_cost.register_sextend);\n-  PARSE_INTEGER_FIELD (jo, \"register_zextend\", addr_cost.register_zextend);\n-  PARSE_INTEGER_FIELD (jo, \"imm_offset\", addr_cost.imm_offset);\n+  PARSE_OBJECT (ctxt, jo, \"addr_scale_costs\", addr_cost.addr_scale_costs, parse_addr_cost_addr_scale_costs);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"pre_modify\", addr_cost.pre_modify);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"post_modify\", addr_cost.post_modify);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"post_modify_ld3_st3\", addr_cost.post_modify_ld3_st3);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"post_modify_ld4_st4\", addr_cost.post_modify_ld4_st4);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"register_offset\", addr_cost.register_offset);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"register_sextend\", addr_cost.register_sextend);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"register_zextend\", addr_cost.register_zextend);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"imm_offset\", addr_cost.imm_offset);\n }\n \n template <typename T>\n static void\n-parse_vec_costs_issue_info (const json::object *jo, T &issue_info)\n+parse_vec_costs_issue_info (gcc_json_context &ctxt, const json::object &jo, T &issue_info)\n {\n-  PARSE_OBJECT (jo, \"scalar\", issue_info.scalar, parse_vec_costs_issue_info_scalar);\n-  PARSE_OBJECT (jo, \"advsimd\", issue_info.advsimd, parse_vec_costs_issue_info_advsimd);\n-  PARSE_OBJECT (jo, \"sve\", issue_info.sve, parse_vec_costs_issue_info_sve);\n+  PARSE_OBJECT (ctxt, jo, \"scalar\", issue_info.scalar, parse_vec_costs_issue_info_scalar);\n+  PARSE_OBJECT (ctxt, jo, \"advsimd\", issue_info.advsimd, parse_vec_costs_issue_info_advsimd);\n+  PARSE_OBJECT (ctxt, jo, \"sve\", issue_info.sve, parse_vec_costs_issue_info_sve);\n }\n \n template <typename T>\n static void\n-parse_vec_costs (const json::object *jo, T &vec_costs)\n+parse_vec_costs (gcc_json_context &ctxt, const json::object &jo, T &vec_costs)\n {\n-  PARSE_INTEGER_FIELD (jo, \"scalar_int_stmt_cost\", vec_costs.scalar_int_stmt_cost);\n-  PARSE_INTEGER_FIELD (jo, \"scalar_fp_stmt_cost\", vec_costs.scalar_fp_stmt_cost);\n-  PARSE_INTEGER_FIELD (jo, \"scalar_load_cost\", vec_costs.scalar_load_cost);\n-  PARSE_INTEGER_FIELD (jo, \"scalar_store_cost\", vec_costs.scalar_store_cost);\n-  PARSE_INTEGER_FIELD (jo, \"cond_taken_branch_cost\", vec_costs.cond_taken_branch_cost);\n-  PARSE_INTEGER_FIELD (jo, \"cond_not_taken_branch_cost\", vec_costs.cond_not_taken_branch_cost);\n-  PARSE_OBJECT (jo, \"advsimd\", vec_costs.advsimd, parse_vec_costs_advsimd);\n-  PARSE_OBJECT (jo, \"sve\", vec_costs.sve, parse_vec_costs_sve);\n-  PARSE_OBJECT (jo, \"issue_info\", vec_costs.issue_info, parse_vec_costs_issue_info);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scalar_int_stmt_cost\", vec_costs.scalar_int_stmt_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scalar_fp_stmt_cost\", vec_costs.scalar_fp_stmt_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scalar_load_cost\", vec_costs.scalar_load_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"scalar_store_cost\", vec_costs.scalar_store_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"cond_taken_branch_cost\", vec_costs.cond_taken_branch_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"cond_not_taken_branch_cost\", vec_costs.cond_not_taken_branch_cost);\n+  PARSE_OBJECT (ctxt, jo, \"advsimd\", vec_costs.advsimd, parse_vec_costs_advsimd);\n+  PARSE_OBJECT (ctxt, jo, \"sve\", vec_costs.sve, parse_vec_costs_sve);\n+  PARSE_OBJECT (ctxt, jo, \"issue_info\", vec_costs.issue_info, parse_vec_costs_issue_info);\n }\n \n template <typename T>\n static void\n-parse_tunings (const json::object *jo, T &tunings)\n+parse_tunings (gcc_json_context &ctxt, const json::object &jo, T &tunings)\n {\n-  PARSE_OBJECT (jo, \"insn_extra_cost\", tunings.insn_extra_cost, parse_insn_extra_cost);\n-  PARSE_OBJECT (jo, \"addr_cost\", tunings.addr_cost, parse_addr_cost);\n-  PARSE_OBJECT (jo, \"regmove_cost\", tunings.regmove_cost, parse_regmove_cost);\n-  PARSE_OBJECT (jo, \"vec_costs\", tunings.vec_costs, parse_vec_costs);\n-  PARSE_OBJECT (jo, \"branch_costs\", tunings.branch_costs, parse_branch_costs);\n-  PARSE_OBJECT (jo, \"approx_modes\", tunings.approx_modes, parse_approx_modes);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"sve_width\", tunings.sve_width);\n-  PARSE_OBJECT (jo, \"memmov_cost\", tunings.memmov_cost, parse_memmov_cost);\n-  PARSE_INTEGER_FIELD (jo, \"issue_rate\", tunings.issue_rate);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"fusible_ops\", tunings.fusible_ops);\n-  PARSE_STRING_FIELD (jo, \"function_align\", tunings.function_align);\n-  PARSE_STRING_FIELD (jo, \"jump_align\", tunings.jump_align);\n-  PARSE_STRING_FIELD (jo, \"loop_align\", tunings.loop_align);\n-  PARSE_INTEGER_FIELD (jo, \"int_reassoc_width\", tunings.int_reassoc_width);\n-  PARSE_INTEGER_FIELD (jo, \"fp_reassoc_width\", tunings.fp_reassoc_width);\n-  PARSE_INTEGER_FIELD (jo, \"fma_reassoc_width\", tunings.fma_reassoc_width);\n-  PARSE_INTEGER_FIELD (jo, \"vec_reassoc_width\", tunings.vec_reassoc_width);\n-  PARSE_INTEGER_FIELD (jo, \"min_div_recip_mul_sf\", tunings.min_div_recip_mul_sf);\n-  PARSE_INTEGER_FIELD (jo, \"min_div_recip_mul_df\", tunings.min_div_recip_mul_df);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"max_case_values\", tunings.max_case_values);\n-  PARSE_ENUM_FIELD (jo, \"autoprefetcher_model\", tunings.autoprefetcher_model, autoprefetcher_model_mappings);\n-  PARSE_UNSIGNED_INTEGER_FIELD (jo, \"extra_tuning_flags\", tunings.extra_tuning_flags);\n-  PARSE_OBJECT (jo, \"prefetch\", tunings.prefetch, parse_prefetch);\n-  PARSE_ENUM_FIELD (jo, \"ldp_policy_model\", tunings.ldp_policy_model, ldp_policy_model_mappings);\n-  PARSE_ENUM_FIELD (jo, \"stp_policy_model\", tunings.stp_policy_model, stp_policy_model_mappings);\n+  PARSE_OBJECT (ctxt, jo, \"insn_extra_cost\", tunings.insn_extra_cost, parse_insn_extra_cost);\n+  PARSE_OBJECT (ctxt, jo, \"addr_cost\", tunings.addr_cost, parse_addr_cost);\n+  PARSE_OBJECT (ctxt, jo, \"regmove_cost\", tunings.regmove_cost, parse_regmove_cost);\n+  PARSE_OBJECT (ctxt, jo, \"vec_costs\", tunings.vec_costs, parse_vec_costs);\n+  PARSE_OBJECT (ctxt, jo, \"branch_costs\", tunings.branch_costs, parse_branch_costs);\n+  PARSE_OBJECT (ctxt, jo, \"approx_modes\", tunings.approx_modes, parse_approx_modes);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"sve_width\", tunings.sve_width);\n+  PARSE_OBJECT (ctxt, jo, \"memmov_cost\", tunings.memmov_cost, parse_memmov_cost);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"issue_rate\", tunings.issue_rate);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"fusible_ops\", tunings.fusible_ops);\n+  PARSE_STRING_FIELD (ctxt, jo, \"function_align\", tunings.function_align);\n+  PARSE_STRING_FIELD (ctxt, jo, \"jump_align\", tunings.jump_align);\n+  PARSE_STRING_FIELD (ctxt, jo, \"loop_align\", tunings.loop_align);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"int_reassoc_width\", tunings.int_reassoc_width);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fp_reassoc_width\", tunings.fp_reassoc_width);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"fma_reassoc_width\", tunings.fma_reassoc_width);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"vec_reassoc_width\", tunings.vec_reassoc_width);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"min_div_recip_mul_sf\", tunings.min_div_recip_mul_sf);\n+  PARSE_INTEGER_FIELD (ctxt, jo, \"min_div_recip_mul_df\", tunings.min_div_recip_mul_df);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"max_case_values\", tunings.max_case_values);\n+  PARSE_ENUM_FIELD (ctxt, jo, \"autoprefetcher_model\", tunings.autoprefetcher_model, autoprefetcher_model_mappings);\n+  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, \"extra_tuning_flags\", tunings.extra_tuning_flags);\n+  PARSE_OBJECT (ctxt, jo, \"prefetch\", tunings.prefetch, parse_prefetch);\n+  PARSE_ENUM_FIELD (ctxt, jo, \"ldp_policy_model\", tunings.ldp_policy_model, ldp_policy_model_mappings);\n+  PARSE_ENUM_FIELD (ctxt, jo, \"stp_policy_model\", tunings.stp_policy_model, stp_policy_model_mappings);\n }\n\\ No newline at end of file\ndiff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc b/gcc/config/aarch64/aarch64-json-tunings-parser.cc\nindex 326d52e02d1ce..40a1cbb41cd71 100644\n--- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc\n+++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc\n@@ -27,6 +27,7 @@\n #include \"tm.h\"\n #include \"diagnostic-core.h\"\n #include \"json-parsing.h\"\n+#include \"json-diagnostic.h\"\n #include \"aarch64-json-schema.h\"\n #include \"aarch64-json-tunings-parser.h\"\n #include \"aarch64-protos.h\"\n@@ -34,45 +35,47 @@\n #include \"selftest.h\"\n #include \"version.h\"\n \n-#define PARSE_INTEGER_FIELD(obj, key, member)                                  \\\n+#define WARNING_OPT (0)\n+\n+#define PARSE_INTEGER_FIELD(ctxt, obj, key, member)                            \\\n   {                                                                            \\\n-    const json::value *val = obj->get (key);                                   \\\n+    const json::value *val = obj.get (key);                                    \\\n     if (val)                                                                   \\\n-      member = extract_integer (val);                                          \\\n+      member = extract_integer (ctxt, *val, WARNING_OPT);                      \\\n   }\n \n-#define PARSE_UNSIGNED_INTEGER_FIELD(obj, key, member)                         \\\n+#define PARSE_UNSIGNED_INTEGER_FIELD(ctxt, obj, key, member)                   \\\n   {                                                                            \\\n-    const json::value *val = obj->get (key);                                   \\\n+    const json::value *val = obj.get (key);                                    \\\n     if (val)                                                                   \\\n-      member = extract_unsigned_integer (val);                                 \\\n+      member = extract_unsigned_integer (ctxt, *val, WARNING_OPT);             \\\n   }\n \n-#define PARSE_BOOLEAN_FIELD(obj, key, member)                                  \\\n+#define PARSE_BOOLEAN_FIELD(ctxt, obj, key, member)                             \\\n   {                                                                            \\\n-    const json::value *val = obj->get (key);                                   \\\n+    const json::value *val = obj.get (key);                                    \\\n     if (val)                                                                   \\\n-      member = extract_boolean (val);                                          \\\n+      member = extract_boolean (ctxt, *val, WARNING_OPT);                      \\\n   }\n \n-#define PARSE_STRING_FIELD(obj, key, member)                                   \\\n+#define PARSE_STRING_FIELD(ctxt, obj, key, member)                             \\\n   {                                                                            \\\n-    const json::value *val = obj->get (key);                                   \\\n+    const json::value *val = obj.get (key);                                    \\\n     if (val)                                                                   \\\n-      member = extract_string (val);                                           \\\n+      member = extract_string (ctxt, *val, WARNING_OPT);                       \\\n   }\n \n-#define PARSE_OBJECT(obj, key, member, parse_func)                             \\\n+#define PARSE_OBJECT(ctxt, obj, key, member, parse_func)                       \\\n   {                                                                            \\\n-    const json::value *field_value = obj->get (key);                           \\\n+    const json::value *field_value = obj.get (key);                            \\\n     if (field_value)                                                           \\\n       if (auto *field_obj = dyn_cast<const json::object *> (field_value))      \\\n-\tparse_object_helper (field_obj, (member), (parse_func));               \\\n+\tparse_object_helper (ctxt, *field_obj, (member), (parse_func));        \\\n   }\n \n-#define PARSE_ARRAY_FIELD(obj, key, member, parse_func)                        \\\n+#define PARSE_ARRAY_FIELD(ctxt, obj, key, member, parse_func)                  \\\n   {                                                                            \\\n-    const json::value *field_value = obj->get (key);                           \\\n+    const json::value *field_value = obj.get (key);                            \\\n     if (field_value)                                                           \\\n       if (auto *field_array = dyn_cast<const json::array *> (field_value))     \\\n \tfor (size_t i = 0; i < field_array->size (); ++i)                      \\\n@@ -80,34 +83,37 @@\n \t    const json::value *elem = field_array->get (i);                    \\\n \t    if (elem)                                                          \\\n \t      if (auto *array_obj = dyn_cast<const json::object *> (elem))     \\\n-\t\tparse_func (array_obj, member[i]);                             \\\n+\t\tparse_func (ctxt, *array_obj, member[i]);                      \\\n \t  }                                                                    \\\n   }\n \n-#define PARSE_ENUM_FIELD(obj, key, member, mappings)                           \\\n-  parse_enum_field (obj, key, member, mappings,                                \\\n-\t\t    sizeof (mappings) / sizeof (mappings[0]))\n+#define PARSE_ENUM_FIELD(ctxt, obj, key, member, mappings)                     \\\n+  parse_enum_field (ctxt, obj, key, member, mappings,                          \\\n+\t\t    sizeof (mappings) / sizeof (mappings[0]), WARNING_OPT)\n \n /* Type alias for parse function pointer.  */\n template <typename T>\n using parse_func_type\n-  = void (*) (const json::object *,\n+  = void (*) (gcc_json_context &,\n+\t      const json::object &,\n \t      std::remove_const_t<std::remove_pointer_t<T>> &);\n \n /* Parse JSON object into non-pointer member type.  */\n template <typename T>\n static std::enable_if_t<!std::is_pointer<T>::value>\n-parse_object_helper (const json::object *field_obj, T &member,\n+parse_object_helper (gcc_json_context &ctxt,\n+\t\t     const json::object &field_obj, T &member,\n \t\t     parse_func_type<T> parse_func)\n {\n-  parse_func (field_obj, member);\n+  parse_func (ctxt, field_obj, member);\n }\n \n /* Parse JSON object into a const pointer member by creating a temp copy.  */\n template <typename T>\n static std::enable_if_t<std::is_pointer<T>::value\n \t\t\t&& std::is_const<std::remove_pointer_t<T>>::value>\n-parse_object_helper (const json::object *field_obj, T &member,\n+parse_object_helper (gcc_json_context &ctxt,\n+\t\t     const json::object &field_obj, T &member,\n \t\t     parse_func_type<T> parse_func)\n {\n   if (!member)\n@@ -120,67 +126,121 @@ parse_object_helper (const json::object *field_obj, T &member,\n   static bool already_initialized = false;\n   if (already_initialized)\n     {\n-      error (\"static storage conflict - multiple pointer members of the \"\n-\t     \"same type cannot be parsed\");\n+      json_error (ctxt, field_obj,\n+\t\t  \"static storage conflict - multiple pointer members of \"\n+\t\t  \"the same type cannot be parsed\");\n       return;\n     }\n   already_initialized = true;\n   using NonConstType = std::remove_const_t<std::remove_pointer_t<T>>;\n   static NonConstType new_obj = *member;\n-  parse_func (field_obj, new_obj);\n+  parse_func (ctxt, field_obj, new_obj);\n   member = &new_obj;\n }\n \n+/* Issue a note about the kind of json value we encountered.  */\n+\n+static void\n+inform_about_wrong_kind_of_json_value (gcc_json_context &ctxt,\n+\t\t\t\t       const json::value &val)\n+{\n+  switch (val.get_kind ())\n+    {\n+    default:\n+      gcc_unreachable ();\n+    case json::JSON_OBJECT:\n+      json_note (ctxt, val, \"...but got an object instead\");\n+      break;\n+    case json::JSON_ARRAY:\n+      json_note (ctxt, val, \"...but got an array instead\");\n+      break;\n+    case json::JSON_INTEGER:\n+      json_note (ctxt, val, \"...but got an integer instead\");\n+      break;\n+    case json::JSON_FLOAT:\n+      json_note (ctxt, val, \"...but got a floating-point value instead\");\n+      break;\n+    case json::JSON_STRING:\n+      json_note (ctxt, val, \"...but got a string instead\");\n+      break;\n+    case json::JSON_TRUE:\n+      json_note (ctxt, val, \"...but got %qs instead\", \"true\");\n+      break;\n+    case json::JSON_FALSE:\n+      json_note (ctxt, val, \"...but got %qs instead\", \"false\");\n+      break;\n+    case json::JSON_NULL:\n+      json_note (ctxt, val, \"...but got %qs instead\", \"null\");\n+      break;\n+    }\n+}\n+\n /* Extract string value from JSON, returning allocated C string.  */\n char *\n-extract_string (const json::value *val)\n+extract_string (gcc_json_context &ctxt,\n+\t\tconst json::value &val,\n+\t\tdiagnostics::option_id warning_opt)\n {\n-  if (auto *string_val = dyn_cast<const json::string *> (val))\n+  if (auto *string_val = dyn_cast<const json::string *> (&val))\n     return xstrdup (string_val->get_string ());\n-  warning (0, \"expected a string but got something else or NULL\");\n+  auto_diagnostic_group d;\n+  if (json_warning (ctxt, val, warning_opt, \"expected a string...\"))\n+    inform_about_wrong_kind_of_json_value (ctxt, val);\n   return nullptr;\n }\n \n /* Extract signed integer value from JSON.  */\n int\n-extract_integer (const json::value *val)\n+extract_integer (gcc_json_context &ctxt,\n+\t\t const json::value &val,\n+\t\t diagnostics::option_id warning_opt)\n {\n-  if (auto *int_val = dyn_cast<const json::integer_number *> (val))\n+  if (auto *int_val = dyn_cast<const json::integer_number *> (&val))\n     {\n       long value = int_val->get ();\n       gcc_assert (value >= INT_MIN && value <= INT_MAX);\n       return static_cast<int> (value);\n     }\n-  warning (0, \"expected an integer value but got something else or NULL\");\n+  auto_diagnostic_group d;\n+  if (json_warning (ctxt, val, warning_opt, \"expected an integer value...\"))\n+    inform_about_wrong_kind_of_json_value (ctxt, val);\n   return 0;\n }\n \n /* Extract unsigned integer value from JSON.  */\n unsigned int\n-extract_unsigned_integer (const json::value *val)\n+extract_unsigned_integer (gcc_json_context &ctxt,\n+\t\t\t  const json::value &val,\n+\t\t\t  diagnostics::option_id warning_opt)\n {\n-  if (auto *int_val = dyn_cast<const json::integer_number *> (val))\n+  if (auto *int_val = dyn_cast<const json::integer_number *> (&val))\n     {\n       long value = int_val->get ();\n       gcc_assert (value >= 0 && value <= UINT_MAX);\n       return static_cast<unsigned int> (value);\n     }\n-  warning (0,\n-\t   \"expected an unsigned integer value but got something else or NULL\");\n+  auto_diagnostic_group d;\n+  if (json_warning (ctxt, val, warning_opt,\n+\t\t    \"expected an unsigned integer value...\"))\n+    inform_about_wrong_kind_of_json_value (ctxt, val);\n   return 0;\n }\n \n /* Extract boolean value from JSON literal.  */\n bool\n-extract_boolean (const json::value *val)\n+extract_boolean (gcc_json_context &ctxt,\n+\t\t const json::value &val,\n+\t\t diagnostics::option_id warning_opt)\n {\n-  if (auto *literal_val = dyn_cast<const json::literal *> (val))\n+  if (auto *literal_val = dyn_cast<const json::literal *> (&val))\n     {\n       json::kind kind = literal_val->get_kind ();\n       if (kind == json::JSON_TRUE || kind == json::JSON_FALSE)\n \treturn (kind == json::JSON_TRUE);\n     }\n-  warning (0, \"expected a boolean value but got something else or NULL\");\n+  auto_diagnostic_group d;\n+  if (json_warning (ctxt, val, warning_opt, \"expected a boolean value...\"))\n+    inform_about_wrong_kind_of_json_value (ctxt, val);\n   return false;\n }\n \n@@ -193,18 +253,21 @@ template <typename EnumType> struct enum_mapping\n /* Parse JSON string field into enum value using string-to-enum mappings.  */\n template <typename EnumType>\n static void\n-parse_enum_field (const json::object *jo, const std::string &key,\n+parse_enum_field (gcc_json_context &ctxt,\n+\t\t  const json::object &jo, const std::string &key,\n \t\t  EnumType &enum_var, const enum_mapping<EnumType> *mappings,\n-\t\t  size_t num_mappings)\n+\t\t  size_t num_mappings,\n+\t\t  diagnostics::option_id warning_opt)\n {\n-  const json::value *field_value = jo->get (key.c_str ());\n+  const json::value *field_value = jo.get (key.c_str ());\n   if (!field_value)\n     return;\n \n   auto *string_val = dyn_cast<const json::string *> (field_value);\n   if (!string_val)\n     {\n-      warning (0, \"expected string for enum field %s\", key.c_str ());\n+      json_warning (ctxt, *field_value, warning_opt,\n+\t\t    \"expected string for enum field %s\", key.c_str ());\n       enum_var = mappings[0].value;\n       return;\n     }\n@@ -219,8 +282,9 @@ parse_enum_field (const json::object *jo, const std::string &key,\n \t}\n     }\n \n-  warning (0, \"%s not recognized, defaulting to %qs\", key.c_str (),\n-\t   mappings[0].name);\n+  json_warning (ctxt, *field_value, 0,\n+\t\t\"%s not recognized, defaulting to %qs\", key.c_str (),\n+\t\tmappings[0].name);\n   enum_var = mappings[0].value;\n }\n \n@@ -230,7 +294,8 @@ parse_enum_field (const json::object *jo, const std::string &key,\n /* Validate the user provided JSON data against the present schema.\n    Checks for correct types, fields, and expected format.  */\n static bool\n-validate_and_traverse (const json::object *json_obj,\n+validate_and_traverse (gcc_json_context &ctxt,\n+\t\t       const json::object *json_obj,\n \t\t       const json::object *schema_obj,\n \t\t       const std::string &parent_key = \"\")\n {\n@@ -244,8 +309,9 @@ validate_and_traverse (const json::object *json_obj,\n       const json::value *schema_value = schema_obj->get (key.c_str ());\n       if (!schema_value)\n \t{\n-\t  warning (0, \"key %qs is not a tuning parameter, skipping\",\n-\t\t   full_key.c_str ());\n+\t  json_warning (ctxt, *json_value, WARNING_OPT,\n+\t\t\t\"key %qs is not a tuning parameter, skipping\",\n+\t\t\tfull_key.c_str ());\n \t  continue;\n \t}\n \n@@ -253,13 +319,15 @@ validate_and_traverse (const json::object *json_obj,\n \t{\n \t  if (auto *sub_json_obj = dyn_cast<const json::object *> (json_value))\n \t    {\n-\t      if (!validate_and_traverse (sub_json_obj, sub_schema_obj,\n+\t      if (!validate_and_traverse (ctxt, sub_json_obj, sub_schema_obj,\n \t\t\t\t\t  full_key))\n \t\treturn false;\n \t    }\n \t  else\n \t    {\n-\t      error (\"key %qs expected to be an object\", full_key.c_str ());\n+\t      json_error (ctxt, *json_value,\n+\t\t\t  \"key %qs expected to be an object\",\n+\t\t\t  full_key.c_str ());\n \t      return false;\n \t    }\n \t}\n@@ -267,7 +335,8 @@ validate_and_traverse (const json::object *json_obj,\n \t{\n \t  if (json_value->get_kind () != json::JSON_ARRAY)\n \t    {\n-\t      error (\"key %qs expected to be an array\", full_key.c_str ());\n+\t      json_error (ctxt, *json_value,\n+\t\t\t  \"key %qs expected to be an array\", full_key.c_str ());\n \t      return false;\n \t    }\n \t}\n@@ -280,8 +349,9 @@ validate_and_traverse (const json::object *json_obj,\n \t    {\n \t      if (json_value->get_kind () != json::JSON_INTEGER)\n \t\t{\n-\t\t  error (\"key %qs expected to be an integer\",\n-\t\t\t full_key.c_str ());\n+\t\t  json_error (ctxt, *json_value,\n+\t\t\t      \"key %qs expected to be an integer\",\n+\t\t\t      full_key.c_str ());\n \t\t  return false;\n \t\t}\n \t      // Check if the value is valid for signed integer\n@@ -291,9 +361,10 @@ validate_and_traverse (const json::object *json_obj,\n \t\t  long value = int_val->get ();\n \t\t  if (value > INT_MAX || value < INT_MIN)\n \t\t    {\n-\t\t      error (\"key %qs value %ld is out of range for %<int%> \"\n-\t\t\t     \"type [%d, %d]\",\n-\t\t\t     full_key.c_str (), value, INT_MIN, INT_MAX);\n+\t\t      json_error (ctxt, *json_value,\n+\t\t\t\t  \"key %qs value %ld is out of range for \"\n+\t\t\t\t  \"%<int%> type [%d, %d]\",\n+\t\t\t\t  full_key.c_str (), value, INT_MIN, INT_MAX);\n \t\t      return false;\n \t\t    }\n \t\t}\n@@ -302,8 +373,9 @@ validate_and_traverse (const json::object *json_obj,\n \t    {\n \t      if (json_value->get_kind () != json::JSON_INTEGER)\n \t\t{\n-\t\t  error (\"key %qs expected to be an unsigned integer\",\n-\t\t\t full_key.c_str ());\n+\t\t  json_error (ctxt, *json_value,\n+\t\t\t      \"key %qs expected to be an unsigned integer\",\n+\t\t\t      full_key.c_str ());\n \t\t  return false;\n \t\t}\n \t      // Check if the value is valid for unsigned integer\n@@ -313,9 +385,10 @@ validate_and_traverse (const json::object *json_obj,\n \t\t  long value = int_val->get ();\n \t\t  if (value < 0 || value > UINT_MAX)\n \t\t    {\n-\t\t      error (\"key %qs value %ld is out of range for %<uint%> \"\n-\t\t\t     \"type [0, %u]\",\n-\t\t\t     full_key.c_str (), value, UINT_MAX);\n+\t\t      json_error (ctxt, *json_value,\n+\t\t\t\t  \"key %qs value %ld is out of range for \"\n+\t\t\t\t  \"%<uint%> type [0, %u]\",\n+\t\t\t\t  full_key.c_str (), value, UINT_MAX);\n \t\t      return false;\n \t\t    }\n \t\t}\n@@ -324,7 +397,9 @@ validate_and_traverse (const json::object *json_obj,\n \t    {\n \t      if (json_value->get_kind () != json::JSON_STRING)\n \t\t{\n-\t\t  error (\"key %qs expected to be a string\", full_key.c_str ());\n+\t\t  json_error (ctxt, *json_value,\n+\t\t\t      \"key %qs expected to be a string\",\n+\t\t\t      full_key.c_str ());\n \t\t  return false;\n \t\t}\n \t    }\n@@ -333,8 +408,9 @@ validate_and_traverse (const json::object *json_obj,\n \t      if (json_value->get_kind () != json::JSON_TRUE\n \t\t  && json_value->get_kind () != json::JSON_FALSE)\n \t\t{\n-\t\t  error (\"key %qs expected to be a boolean (true/false)\",\n-\t\t\t full_key.c_str ());\n+\t\t  json_error (ctxt, *json_value,\n+\t\t\t      \"key %qs expected to be a boolean (true/false)\",\n+\t\t\t      full_key.c_str ());\n \t\t  return false;\n \t\t}\n \t    }\n@@ -342,20 +418,24 @@ validate_and_traverse (const json::object *json_obj,\n \t    {\n \t      if (json_value->get_kind () != json::JSON_STRING)\n \t\t{\n-\t\t  error (\"key %qs expected to be an enum (string)\",\n-\t\t\t full_key.c_str ());\n+\t\t  json_error (ctxt, *json_value,\n+\t\t\t      \"key %qs expected to be an enum (string)\",\n+\t\t\t      full_key.c_str ());\n \t\t  return false;\n \t\t}\n \t    }\n \t  else\n \t    {\n-\t      error (\"key %qs has unsupported type\", full_key.c_str ());\n+\t      json_error (ctxt, *json_value,\n+\t\t\t  \"key %qs has unsupported type\", full_key.c_str ());\n \t      return false;\n \t    }\n \t}\n       else\n \t{\n-\t  error (\"key %qs has unexpected format in schema\", full_key.c_str ());\n+\t  json_error (ctxt, *json_value,\n+\t\t      \"key %qs has unexpected format in schema\",\n+\t\t      full_key.c_str ());\n \t  return false;\n \t}\n     }\n@@ -413,13 +493,15 @@ check_version_compatibility (const json::object *root_obj)\n \n   if (json_gcc_major_version == -1)\n     {\n-      warning (0, \"JSON tuning file does not contain version information; \"\n-\t\t  \"compatibility cannot be verified\");\n+      warning (WARNING_OPT,\n+\t       \"JSON tuning file does not contain version information; \"\n+\t       \"compatibility cannot be verified\");\n       return true;\n     }\n \n   if (json_gcc_major_version != GCC_major_version)\n     {\n+      auto_diagnostic_group d;\n       error (\"JSON tuning file was created with GCC version %d \"\n \t     \"but current GCC version is %d\",\n \t     json_gcc_major_version, GCC_major_version);\n@@ -433,31 +515,32 @@ check_version_compatibility (const json::object *root_obj)\n \n /* Main routine for setting up the parsing of JSON data.  */\n static void\n-aarch64_load_tuning_params_from_json_string (const char *json_string,\n+aarch64_load_tuning_params_from_json_string (const char *js_filename,\n+\t\t\t\t\t     const char *json_string,\n \t\t\t\t\t     const char *schema_string,\n \t\t\t\t\t     struct tune_params *tune)\n {\n   /* Try parsing the JSON string.  */\n+  gcc_json_context ctxt (js_filename);\n   json::parser_result_t data_result\n     = json::parse_utf8_string (strlen (json_string), json_string, true,\n-\t\t\t       nullptr);\n+\t\t\t       &ctxt);\n \n   if (auto json_err = data_result.m_err.get ())\n     {\n-      error (\"error parsing JSON data: %s\", json_err->get_msg ());\n+      location_t js_loc = ctxt.make_location_for_range (json_err->get_range ());\n+      error_at (js_loc, \"error parsing JSON data: %s\", json_err->get_msg ());\n       return;\n     }\n \n-  const std::unique_ptr<json::value> &root = data_result.m_val;\n-  if (!root)\n-    {\n-      error (\"JSON parsing returned null data\");\n-      return;\n-    }\n-  auto *root_obj = dyn_cast<const json::object *> (root.get ());\n+  const json::value* root = data_result.m_val.get ();\n+  gcc_assert (root);\n+\n+  auto *root_obj = dyn_cast<const json::object *> (root);\n   if (!root_obj)\n     {\n-      warning (0, \"no JSON object found in the provided data\");\n+      json_warning (ctxt, *root, WARNING_OPT,\n+\t\t    \"no JSON object found in the provided data\");\n       return;\n     }\n \n@@ -479,24 +562,26 @@ aarch64_load_tuning_params_from_json_string (const char *json_string,\n   const json::value *tune_params_value = root_obj->get (\"tune_params\");\n   if (!tune_params_value)\n     {\n-      warning (0, \"key %<tune_params%> not found in JSON data\");\n+      json_warning (ctxt, *root_obj, WARNING_OPT,\n+\t\t    \"key %<tune_params%> not found in JSON data\");\n       return;\n     }\n \n   auto *jo = dyn_cast<const json::object *> (tune_params_value);\n   if (!jo)\n     {\n-      error (\"key %<tune_params%> is not a JSON object\");\n+      json_error (ctxt, *tune_params_value,\n+\t\t  \"key %<tune_params%> is not a JSON object\");\n       return;\n     }\n \n-  if (!validate_and_traverse (root_obj, schema_obj))\n+  if (!validate_and_traverse (ctxt, root_obj, schema_obj))\n     {\n       error (\"validation failed for the provided JSON data\");\n       return;\n     }\n \n-  parse_tunings (jo, *tune);\n+  parse_tunings (ctxt, *jo, *tune);\n   return;\n }\n \n@@ -511,8 +596,9 @@ aarch64_load_tuning_params_from_json (const char *data_filename,\n       error (\"cannot read JSON data in %s\", data_filename);\n       return;\n     }\n-  aarch64_load_tuning_params_from_json_string (\n-    (const char *) json_data->data (), schema_json, tune);\n+  aarch64_load_tuning_params_from_json_string\n+    (data_filename,\n+     (const char *) json_data->data (), schema_json, tune);\n }\n \n #if CHECKING_P\n@@ -536,7 +622,8 @@ test_json_integers ()\n \n   tune_params params;\n \n-  aarch64_load_tuning_params_from_json_string (test_json, schema_json, &params);\n+  aarch64_load_tuning_params_from_json_string\n+    (\"test.json\", test_json, schema_json, &params);\n \n   ASSERT_EQ (params.sve_width, 256);\n   ASSERT_EQ (params.issue_rate, 4);\n@@ -563,7 +650,8 @@ test_json_boolean ()\n   tune_params params;\n   params.insn_extra_cost = &default_cost_table;\n \n-  aarch64_load_tuning_params_from_json_string (test_json, schema_json, &params);\n+  aarch64_load_tuning_params_from_json_string\n+    (\"test.json\", test_json, schema_json, &params);\n \n   ASSERT_EQ (params.insn_extra_cost->alu.non_exec_costs_exec, false);\n }\n@@ -584,7 +672,8 @@ test_json_strings ()\n \n   tune_params params;\n \n-  aarch64_load_tuning_params_from_json_string (test_json, schema_json, &params);\n+  aarch64_load_tuning_params_from_json_string\n+    (\"test.json\", test_json, schema_json, &params);\n \n   ASSERT_STREQ (params.function_align, \"16\");\n   ASSERT_STREQ (params.jump_align, \"2\");\n@@ -607,7 +696,8 @@ test_json_enums ()\n \n   tune_params params;\n \n-  aarch64_load_tuning_params_from_json_string (test_json, schema_json, &params);\n+  aarch64_load_tuning_params_from_json_string\n+    (\"test.json\", test_json, schema_json, &params);\n \n   ASSERT_EQ (params.autoprefetcher_model, tune_params::AUTOPREFETCHER_OFF);\n   ASSERT_EQ (params.ldp_policy_model, AARCH64_LDP_STP_POLICY_NEVER);\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c\nindex aef632f1d0423..0ed8f71b775d0 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c\n@@ -1,8 +1,16 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-2.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* expected to be a boolean\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json: In JSON value '/tune_params/insn_extra_cost/alu/non_exec_costs_exec'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json:5:32: error: key .* expected to be a boolean \\\\\\(true/false\\\\\\)\"  } */\n+/* { dg-begin-multiline-output \"\" }\n+    5 |         \"non_exec_costs_exec\": 0\n+      |                                ^\n+   { dg-end-multiline-output \"\" } */\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c\nindex 4df72dbaf7ab4..cbbe8afe760ec 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c\n@@ -1,7 +1,12 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-warning \"key 'tune_params' not found in JSON data\"  \"\" { target *-*-* } 0 } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json:1:1: warning: key 'tune_params' not found in JSON data\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    1 | {}\n+      | ^~\n+   { dg-end-multiline-output \"\" } */\n \n-int main () {}\n\\ No newline at end of file\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c\nindex c53bc5292d52f..30e0fd47d7946 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c\n@@ -1,8 +1,21 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-2.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-warning \"autoprefetcher_model not recognized, defaulting to 'AUTOPREFETCHER_OFF'\"  \"\" { target *-*-* } 0 } */\n-/* { dg-warning \"ldp_policy_model not recognized, defaulting to 'AARCH64_LDP_STP_POLICY_DEFAULT'\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In JSON value '/tune_params/autoprefetcher_model'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:3:29: warning: autoprefetcher_model not recognized, defaulting to 'AUTOPREFETCHER_OFF'\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"autoprefetcher_model\": \"null\",\n+      |                             ^~~~~~\n+   { dg-end-multiline-output \"\" } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In JSON value '/tune_params/ldp_policy_model'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:4:25: warning: ldp_policy_model not recognized, defaulting to 'AARCH64_LDP_STP_POLICY_DEFAULT'\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    4 |     \"ldp_policy_model\": \"null\",\n+      |                         ^~~~~~\n+   { dg-end-multiline-output \"\" } */\n+\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c\nindex 093c86048ce95..4e9de75a7aa7d 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c\n@@ -1,8 +1,16 @@\n /* { dg-do compile } */\n-/* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json -fdump-tuning-model=temp.json \" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* value .* is out of range for 'int' type\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json: In JSON value '/tune_params/int_reassoc_width'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json:3:26: error: key .* value .* is out of range for 'int' type \\\\\\[.*, .*\\\\\\]\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"int_reassoc_width\": 12097307449014\n+      |                          ^~~~~~~~~~~~~~\n+   { dg-end-multiline-output \"\" } */\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c\nindex 438685c6002c6..bab713b35d03f 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c\n@@ -1,8 +1,17 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-3.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* expected to be an integer\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json: In JSON value '/tune_params/issue_rate'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json:3:19: error: key .* expected to be an integer\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"issue_rate\": \"10\"\n+      |                   ^~~~\n+   { dg-end-multiline-output \"\" } */\n+\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c\nnew file mode 100644\nindex 0000000000000..f4d6bc0a1376c\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c\n@@ -0,0 +1,11 @@\n+/* { dg-do compile } */\n+/* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/malformed.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/malformed.json:3:17: error: error parsing JSON data: expected ':'; got number\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"sve_width\" 128\n+      |                 ^~~\n+   { dg-end-multiline-output \"\" } */\n+\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json\nnew file mode 100644\nindex 0000000000000..541b721faccde\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json\n@@ -0,0 +1,5 @@\n+{\n+  \"tune_params\": {\n+    \"sve_width\" 128\n+  }\n+}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c\nindex ad3ea1422bade..ae6e265c514ac 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c\n@@ -1,8 +1,16 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-2.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* expected to be a string\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/string-2.json: In JSON value '/tune_params/function_align'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/string-2.json:3:23: error: key .* expected to be a string\"  \"\" { target *-*-* } 0 } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"function_align\": 16\n+      |                       ^~\n+   { dg-end-multiline-output \"\" } */\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c\nindex bafbda8a1ef57..27bfacc40203d 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c\n@@ -1,7 +1,15 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-warning \"key .* is not a tuning parameter, skipping\"  \"\" { target *-*-* } 0 } */\n \n-int main () {}\n\\ No newline at end of file\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json: In JSON value '/tune_params/unidentified_key'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json:3:25: warning: key .* is not a tuning parameter, skipping\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"unidentified_key\": \"10\"\n+      |                         ^~~~\n+   { dg-end-multiline-output \"\" } */\n+\n+int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c\nindex ce1989d8e31df..88848e406cc0a 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c\n@@ -1,8 +1,16 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* value .* is out of range for 'uint' type\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json: In JSON value '/tune_params/sve_width'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json:3:18: error: key .* value .* is out of range for 'uint' type \\\\\\[.*, .*\\\\\\]\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"sve_width\": -128,\n+      |                  ^~~~\n+   { dg-end-multiline-output \"\" } */\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n int main () {}\ndiff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c\nindex 20a661f557026..0e808009810ef 100644\n--- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c\n+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c\n@@ -1,8 +1,16 @@\n /* { dg-do compile } */\n /* { dg-additional-options \"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json -fdump-tuning-model=temp.json\" } */\n+/* { dg-additional-options \"-fdiagnostics-show-caret -fdiagnostics-show-line-numbers\" } */\n \n /* { dg-warning \"JSON tuning file does not contain version information\" \"\" { target *-*-* } 0 } */\n-/* { dg-error \"key .* value .* is out of range for 'uint' type\"  \"\" { target *-*-* } 0 } */\n+\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json: In JSON value '/tune_params/sve_width'\" } */\n+/* { dg-regexp \".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json:3:18: error: key .* value .* is out of range for 'uint' type \\\\\\[.*, .*\\\\\\]\" } */\n+/* { dg-begin-multiline-output \"\" }\n+    3 |     \"sve_width\": 5000000000\n+      |                  ^~~~~~~~~~\n+   { dg-end-multiline-output \"\" } */\n+\n /* { dg-error \"validation failed for the provided JSON data\"  \"\" { target *-*-* } 0 } */\n \n int main () {}\n",
    "prefixes": [
        "5/5"
    ]
}