On Sat, Feb 14, 2026 at 7:55 AM David Malcolm <[email protected]> wrote:
>
> Use json-diagnostic.{h,cc} to improve the diagnostics issued
> for malformed and invalid JSON tuning inputs: report the
> file/line/column and, if possible, the JSON Pointer of the
> problematic input.
>
> Before
> ------
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json
> cc1: error: error parsing JSON data: expected ':'; got number
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json
> cc1: warning: JSON tuning file does not contain version information; 
> compatibility cannot be verified
> cc1: error: key ‘tune_params.sve_width’ value 5000000000 is out of range for 
> ‘uint’ type [0, 4294967295]
> cc1: error: validation failed for the provided JSON data
>
> After
> -----
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json
> malformed.json:3:17: error: error parsing JSON data: expected ':'; got number
>     3 |     "sve_width" 128
>       |                 ^~~
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json
> cc1: warning: JSON tuning file does not contain version information; 
> compatibility cannot be verified
> unsigned-3.json: In JSON value ‘/tune_params/sve_width’
> unsigned-3.json:3:18: error: key ‘tune_params.sve_width’ value 5000000000 is 
> out of range for ‘uint’ type [0, 4294967295]
>     3 |     "sve_width": 5000000000
>       |                  ^~~~~~~~~~
> cc1: error: validation failed for the provided JSON data
>
> gcc/ChangeLog:
>         PR target/124094
>         * config/aarch64/aarch64-generate-json-tuning-routines.py
>         (generate_field_code): Add "ctxt, " arg to function call when
>         operation is "parse".
>         (generate_function): Add "gcc_json_context &ctxt, " param to
>         function decl when operation is "parse".
>         * config/aarch64/aarch64-json-tunings-parser-generated.inc:
>         Regenerate, passing around a gcc_json_context &.
>         * config/aarch64/aarch64-json-tunings-parser.cc: Include
>         "json-diagnostic.h".
>         (WARNING_OPT) New macro.
>         (PARSE_INTEGER_FIELD): Add "ctxt" param and pass it around.
>         (PARSE_UNSIGNED_INTEGER_FIELD): Likewise.
>         (PARSE_BOOLEAN_FIELD): Likewise.
>         (PARSE_STRING_FIELD): Likewise.
>         (PARSE_OBJECT): Likewise.
>         (PARSE_ARRAY_FIELD): Likewise.
>         (PARSE_ENUM_FIELD): Likewise.
>         (parse_func_type): Likewise.
>         (parse_object_helper): Likewise.  Use json_error rather than error.
>         (inform_about_wrong_kind_of_json_value): New.
>         (extract_string): Add "ctxt" param.  Replace "warning" with a pair
>         of calls to json_warning and
>         inform_about_wrong_kind_of_json_value, tweaking wording
>         accordingly.
>         (extract_integer): Likewise.
>         (extract_unsigned_integer): Likewise.
>         (parse_enum_field): Likewise.
>         (validate_and_traverse): Replace "warning" and "error" with
>         "json_warning" and "json_error".
>         (check_version_compatibility): Use WARNING_OPT.  Add
>         auto_diagnostic_group to group the error and note.
>         (aarch64_load_tuning_params_from_json_string): Add "js_filename"
>         param.  Use gcc_json_context to capture location info.  Use it
>         when reporting errors to get file/line/column info.  Replace check
>         on root being non-null with assertion, as this is guaranteed if
>         error is non-null.  Replace warning with json_warning.
>         (aarch64_load_tuning_params_from_json): Pass data_filename to
>         aarch64_load_tuning_params_from_json_string for use when reporting
>         diagnostics.
>         (selftest::test_json_integers): Add a placeholder filename.
>         (selftest::test_json_boolean): Likewise.
>         (selftest::test_json_strings): Likewise.
>         (selftest::test_json_enums): Likewise.
>
> gcc/testsuite/ChangeLog:
>         PR target/124094
>         * gcc.target/aarch64/aarch64-json-tunings/boolean-2.c: Add options
>         -fdiagnostics-show-caret -fdiagnostics-show-line-numbers.  Replace
>         dg-error with a pair of dg-regexps to verify that we report the
>         filename and JSON Pointer of where the error occurs, and then
>         the filename and location within the JSON file.  Verify that we
>         quote and underline the pertinent part of the JSON file.
>         * gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/enum-2.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/integer-2.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/integer-3.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/string-2.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c: 
> Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c: Likewise.
>         * gcc.target/aarch64/aarch64-json-tunings/malformed.c: New test,
>         to verify behavior on a malformed JSON input file.
>         * gcc.target/aarch64/aarch64-json-tunings/malformed.json: New
>         test file.  This is malformed JSON, due to a missing ':" between
>         key and value.
>
> Signed-off-by: David Malcolm <[email protected]>
> ---
>  .../aarch64-generate-json-tuning-routines.py  |  17 +-
>  .../aarch64-json-tunings-parser-generated.inc | 428 +++++++++---------
>  .../aarch64/aarch64-json-tunings-parser.cc    | 276 +++++++----
>  .../aarch64/aarch64-json-tunings/boolean-2.c  |  12 +-
>  .../aarch64-json-tunings/empty-brackets.c     |   9 +-
>  .../aarch64/aarch64-json-tunings/enum-2.c     |  19 +-
>  .../aarch64/aarch64-json-tunings/integer-2.c  |  14 +-
>  .../aarch64/aarch64-json-tunings/integer-3.c  |  13 +-
>  .../aarch64/aarch64-json-tunings/malformed.c  |  11 +
>  .../aarch64-json-tunings/malformed.json       |   5 +
>  .../aarch64/aarch64-json-tunings/string-2.c   |  12 +-
>  .../aarch64-json-tunings/unidentified-key.c   |  12 +-
>  .../aarch64/aarch64-json-tunings/unsigned-2.c |  10 +-
>  .../aarch64/aarch64-json-tunings/unsigned-3.c |  10 +-
>  14 files changed, 517 insertions(+), 331 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
>
> diff --git a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py 
> b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> index a4f9e4ece71a3..9253cf58cdfa1 100755
> --- a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> +++ b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> @@ -85,15 +85,20 @@ def generate_field_code(
>  ) -> List[str]:
>      lines = []
>
> +    if operation == 'parse':
> +        ctxt = 'ctxt, '
> +    else:
> +        ctxt = ''

What about passing around a ctxt pointer aways and then for the non
parse case just pass a null pointer?
Just in case we need a context later on for the output case and don't
need to change this part again.

Otherwise this looks ok to me.

Thanks,
Andrew Pinski



> +
>      if isinstance(value, str):
>          macro = get_macro(operation.upper(), value)
>          if value == "enum":
>              enum_mapping = f"{key}_mappings"
>              lines.append(
> -                f'{indent}{macro} ({obj_name}, "{key}", {struct_name}.{key}, 
> {enum_mapping});'
> +                f'{indent}{macro} ({ctxt}{obj_name}, "{key}", 
> {struct_name}.{key}, {enum_mapping});'
>              )
>          else:
> -            lines.append(f'{indent}{macro} ({obj_name}, "{key}", 
> {struct_name}.{key});')
> +            lines.append(f'{indent}{macro} ({ctxt}{obj_name}, "{key}", 
> {struct_name}.{key});')
>
>      elif isinstance(value, dict):
>          # Nested object - find function name based on current context + key
> @@ -102,7 +107,7 @@ def generate_field_code(
>          func_name = function_map.get(child_path_key, 
> f"{operation.lower()}_{key}")
>          macro_name = f"{operation.upper()}_OBJECT"
>          lines.append(
> -            f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
> +            f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
>          )
>
>      elif isinstance(value, list) and len(value) > 0:
> @@ -117,11 +122,11 @@ def generate_field_code(
>
>              if operation.lower() == "serialize":
>                  lines.append(
> -                    f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'
> +                    f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", 
> {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'
>                  )
>              else:
>                  lines.append(
> -                    f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
> +                    f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
>                  )
>          else:
>              raise ValueError(f"Arrays of non-object types are not yet 
> supported: {key}")
> @@ -175,7 +180,7 @@ def generate_function(
>
>      if operation.lower() == "parse":
>          lines.append("static void")
> -        lines.append(f"parse_{full_name} (const json::object *jo, T 
> &{local_name})")
> +        lines.append(f"parse_{full_name} (gcc_json_context &ctxt, const 
> json::object &jo, T &{local_name})")
>          lines.append("{")
>
>          for key, value in schema.items():
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc 
> b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> index 882d8f799755a..3908a4f1a3114 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> @@ -38,319 +38,319 @@ static const enum_mapping<aarch64_ldp_stp_policy> 
> stp_policy_model_mappings[] =
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost_alu (const json::object *jo, T &alu)
> +parse_insn_extra_cost_alu (gcc_json_context &ctxt, const json::object &jo, T 
> &alu)
>  {
> -  PARSE_INTEGER_FIELD (jo, "arith", alu.arith);
> -  PARSE_INTEGER_FIELD (jo, "logical", alu.logical);
> -  PARSE_INTEGER_FIELD (jo, "shift", alu.shift);
> -  PARSE_INTEGER_FIELD (jo, "shift_reg", alu.shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "arith_shift", alu.arith_shift);
> -  PARSE_INTEGER_FIELD (jo, "arith_shift_reg", alu.arith_shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "log_shift", alu.log_shift);
> -  PARSE_INTEGER_FIELD (jo, "log_shift_reg", alu.log_shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "extend", alu.extend);
> -  PARSE_INTEGER_FIELD (jo, "extend_arith", alu.extend_arith);
> -  PARSE_INTEGER_FIELD (jo, "bfi", alu.bfi);
> -  PARSE_INTEGER_FIELD (jo, "bfx", alu.bfx);
> -  PARSE_INTEGER_FIELD (jo, "clz", alu.clz);
> -  PARSE_INTEGER_FIELD (jo, "rev", alu.rev);
> -  PARSE_INTEGER_FIELD (jo, "non_exec", alu.non_exec);
> -  PARSE_BOOLEAN_FIELD (jo, "non_exec_costs_exec", alu.non_exec_costs_exec);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "arith", alu.arith);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "logical", alu.logical);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "shift", alu.shift);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "shift_reg", alu.shift_reg);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift", alu.arith_shift);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift_reg", alu.arith_shift_reg);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "log_shift", alu.log_shift);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "log_shift_reg", alu.log_shift_reg);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "extend", alu.extend);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "extend_arith", alu.extend_arith);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "bfi", alu.bfi);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "bfx", alu.bfx);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "clz", alu.clz);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "rev", alu.rev);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "non_exec", alu.non_exec);
> +  PARSE_BOOLEAN_FIELD (ctxt, jo, "non_exec_costs_exec", 
> alu.non_exec_costs_exec);
>  }
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost_mult_element (const json::object *jo, T &mult_element)
> +parse_insn_extra_cost_mult_element (gcc_json_context &ctxt, const 
> json::object &jo, T &mult_element)
>  {
> -  PARSE_INTEGER_FIELD (jo, "simple", mult_element.simple);
> -  PARSE_INTEGER_FIELD (jo, "flag_setting", mult_element.flag_setting);
> -  PARSE_INTEGER_FIELD (jo, "extend", mult_element.extend);
> -  PARSE_INTEGER_FIELD (jo, "add", mult_element.add);
> -  PARSE_INTEGER_FIELD (jo, "extend_add", mult_element.extend_add);
> -  PARSE_INTEGER_FIELD (jo, "idiv", mult_element.idiv);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "simple", mult_element.simple);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "flag_setting", mult_element.flag_setting);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "extend", mult_element.extend);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "add", mult_element.add);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "extend_add", mult_element.extend_add);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "idiv", mult_element.idiv);
>  }
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost_ldst (const json::object *jo, T &ldst)
> +parse_insn_extra_cost_ldst (gcc_json_context &ctxt, const json::object &jo, 
> T &ldst)
>  {
> -  PARSE_INTEGER_FIELD (jo, "load", ldst.load);
> -  PARSE_INTEGER_FIELD (jo, "load_sign_extend", ldst.load_sign_extend);
> -  PARSE_INTEGER_FIELD (jo, "ldrd", ldst.ldrd);
> -  PARSE_INTEGER_FIELD (jo, "ldm_1st", ldst.ldm_1st);
> -  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_1st", 
> ldst.ldm_regs_per_insn_1st);
> -  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_subsequent", 
> ldst.ldm_regs_per_insn_subsequent);
> -  PARSE_INTEGER_FIELD (jo, "loadf", ldst.loadf);
> -  PARSE_INTEGER_FIELD (jo, "loadd", ldst.loadd);
> -  PARSE_INTEGER_FIELD (jo, "load_unaligned", ldst.load_unaligned);
> -  PARSE_INTEGER_FIELD (jo, "store", ldst.store);
> -  PARSE_INTEGER_FIELD (jo, "strd", ldst.strd);
> -  PARSE_INTEGER_FIELD (jo, "stm_1st", ldst.stm_1st);
> -  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_1st", 
> ldst.stm_regs_per_insn_1st);
> -  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_subsequent", 
> ldst.stm_regs_per_insn_subsequent);
> -  PARSE_INTEGER_FIELD (jo, "storef", ldst.storef);
> -  PARSE_INTEGER_FIELD (jo, "stored", ldst.stored);
> -  PARSE_INTEGER_FIELD (jo, "store_unaligned", ldst.store_unaligned);
> -  PARSE_INTEGER_FIELD (jo, "loadv", ldst.loadv);
> -  PARSE_INTEGER_FIELD (jo, "storev", ldst.storev);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load", ldst.load);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load_sign_extend", ldst.load_sign_extend);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ldrd", ldst.ldrd);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ldm_1st", ldst.ldm_1st);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_1st", 
> ldst.ldm_regs_per_insn_1st);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_subsequent", 
> ldst.ldm_regs_per_insn_subsequent);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "loadf", ldst.loadf);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "loadd", ldst.loadd);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load_unaligned", ldst.load_unaligned);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store", ldst.store);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "strd", ldst.strd);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "stm_1st", ldst.stm_1st);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_1st", 
> ldst.stm_regs_per_insn_1st);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_subsequent", 
> ldst.stm_regs_per_insn_subsequent);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "storef", ldst.storef);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "stored", ldst.stored);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_unaligned", ldst.store_unaligned);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "loadv", ldst.loadv);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "storev", ldst.storev);
>  }
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element)
> +parse_insn_extra_cost_fp_element (gcc_json_context &ctxt, const json::object 
> &jo, T &fp_element)
>  {
> -  PARSE_INTEGER_FIELD (jo, "div", fp_element.div);
> -  PARSE_INTEGER_FIELD (jo, "mult", fp_element.mult);
> -  PARSE_INTEGER_FIELD (jo, "mult_addsub", fp_element.mult_addsub);
> -  PARSE_INTEGER_FIELD (jo, "fma", fp_element.fma);
> -  PARSE_INTEGER_FIELD (jo, "addsub", fp_element.addsub);
> -  PARSE_INTEGER_FIELD (jo, "fpconst", fp_element.fpconst);
> -  PARSE_INTEGER_FIELD (jo, "neg", fp_element.neg);
> -  PARSE_INTEGER_FIELD (jo, "compare", fp_element.compare);
> -  PARSE_INTEGER_FIELD (jo, "widen", fp_element.widen);
> -  PARSE_INTEGER_FIELD (jo, "narrow", fp_element.narrow);
> -  PARSE_INTEGER_FIELD (jo, "toint", fp_element.toint);
> -  PARSE_INTEGER_FIELD (jo, "fromint", fp_element.fromint);
> -  PARSE_INTEGER_FIELD (jo, "roundint", fp_element.roundint);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "div", fp_element.div);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "mult", fp_element.mult);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "mult_addsub", fp_element.mult_addsub);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fma", fp_element.fma);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "addsub", fp_element.addsub);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fpconst", fp_element.fpconst);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "neg", fp_element.neg);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "compare", fp_element.compare);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "widen", fp_element.widen);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "narrow", fp_element.narrow);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "toint", fp_element.toint);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fromint", fp_element.fromint);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "roundint", fp_element.roundint);
>  }
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost_vect (const json::object *jo, T &vect)
> +parse_insn_extra_cost_vect (gcc_json_context &ctxt, const json::object &jo, 
> T &vect)
>  {
> -  PARSE_INTEGER_FIELD (jo, "alu", vect.alu);
> -  PARSE_INTEGER_FIELD (jo, "mult", vect.mult);
> -  PARSE_INTEGER_FIELD (jo, "movi", vect.movi);
> -  PARSE_INTEGER_FIELD (jo, "dup", vect.dup);
> -  PARSE_INTEGER_FIELD (jo, "extract", vect.extract);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "alu", vect.alu);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "mult", vect.mult);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "movi", vect.movi);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "dup", vect.dup);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "extract", vect.extract);
>  }
>
>  template <typename T>
>  static void
> -parse_addr_cost_addr_scale_costs (const json::object *jo, T 
> &addr_scale_costs)
> +parse_addr_cost_addr_scale_costs (gcc_json_context &ctxt, const json::object 
> &jo, T &addr_scale_costs)
>  {
> -  PARSE_INTEGER_FIELD (jo, "hi", addr_scale_costs.hi);
> -  PARSE_INTEGER_FIELD (jo, "si", addr_scale_costs.si);
> -  PARSE_INTEGER_FIELD (jo, "di", addr_scale_costs.di);
> -  PARSE_INTEGER_FIELD (jo, "ti", addr_scale_costs.ti);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "hi", addr_scale_costs.hi);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "si", addr_scale_costs.si);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "di", addr_scale_costs.di);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ti", addr_scale_costs.ti);
>  }
>
>  template <typename T>
>  static void
> -parse_regmove_cost (const json::object *jo, T &regmove_cost)
> +parse_regmove_cost (gcc_json_context &ctxt, const json::object &jo, T 
> &regmove_cost)
>  {
> -  PARSE_INTEGER_FIELD (jo, "GP2GP", regmove_cost.GP2GP);
> -  PARSE_INTEGER_FIELD (jo, "GP2FP", regmove_cost.GP2FP);
> -  PARSE_INTEGER_FIELD (jo, "FP2GP", regmove_cost.FP2GP);
> -  PARSE_INTEGER_FIELD (jo, "FP2FP", regmove_cost.FP2FP);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "GP2GP", regmove_cost.GP2GP);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "GP2FP", regmove_cost.GP2FP);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "FP2GP", regmove_cost.FP2GP);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "FP2FP", regmove_cost.FP2FP);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_advsimd (const json::object *jo, T &advsimd)
> +parse_vec_costs_advsimd (gcc_json_context &ctxt, const json::object &jo, T 
> &advsimd)
>  {
> -  PARSE_INTEGER_FIELD (jo, "int_stmt_cost", advsimd.int_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld2_st2_permute_cost", 
> advsimd.ld2_st2_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld3_st3_permute_cost", 
> advsimd.ld3_st3_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld4_st4_permute_cost", 
> advsimd.ld4_st4_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "permute_cost", advsimd.permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> -  PARSE_INTEGER_FIELD (jo, "store_elt_extra_cost", 
> advsimd.store_elt_extra_cost);
> -  PARSE_INTEGER_FIELD (jo, "vec_to_scalar_cost", advsimd.vec_to_scalar_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_to_vec_cost", advsimd.scalar_to_vec_cost);
> -  PARSE_INTEGER_FIELD (jo, "align_load_cost", advsimd.align_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "unalign_load_cost", advsimd.unalign_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "unalign_store_cost", advsimd.unalign_store_cost);
> -  PARSE_INTEGER_FIELD (jo, "store_cost", advsimd.store_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "int_stmt_cost", advsimd.int_stmt_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ld2_st2_permute_cost", 
> advsimd.ld2_st2_permute_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ld3_st3_permute_cost", 
> advsimd.ld3_st3_permute_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "ld4_st4_permute_cost", 
> advsimd.ld4_st4_permute_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "permute_cost", advsimd.permute_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_elt_extra_cost", 
> advsimd.store_elt_extra_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "vec_to_scalar_cost", 
> advsimd.vec_to_scalar_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scalar_to_vec_cost", 
> advsimd.scalar_to_vec_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "align_load_cost", advsimd.align_load_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "unalign_load_cost", 
> advsimd.unalign_load_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "unalign_store_cost", 
> advsimd.unalign_store_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_cost", advsimd.store_cost);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_sve (const json::object *jo, T &sve)
> +parse_vec_costs_sve (gcc_json_context &ctxt, const json::object &jo, T &sve)
>  {
> -  PARSE_INTEGER_FIELD (jo, "clast_cost", sve.clast_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f16_cost", sve.fadda_f16_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f32_cost", sve.fadda_f32_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f64_cost", sve.fadda_f64_cost);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_load_x32_cost", 
> sve.gather_load_x32_cost);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_load_x64_cost", 
> sve.gather_load_x64_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x32_init_cost", 
> sve.gather_load_x32_init_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x64_init_cost", 
> sve.gather_load_x64_init_cost);
> -  PARSE_INTEGER_FIELD (jo, "scatter_store_elt_cost", 
> sve.scatter_store_elt_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "clast_cost", sve.clast_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f16_cost", sve.fadda_f16_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f32_cost", sve.fadda_f32_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f64_cost", sve.fadda_f64_cost);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x32_cost", 
> sve.gather_load_x32_cost);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x64_cost", 
> sve.gather_load_x64_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x32_init_cost", 
> sve.gather_load_x32_init_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x64_init_cost", 
> sve.gather_load_x64_init_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scatter_store_elt_cost", 
> sve.scatter_store_elt_cost);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_issue_info_scalar (const json::object *jo, T &scalar)
> +parse_vec_costs_issue_info_scalar (gcc_json_context &ctxt, const 
> json::object &jo, T &scalar)
>  {
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> scalar.loads_stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", 
> scalar.stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> scalar.general_ops_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> scalar.fp_simd_load_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> scalar.fp_simd_store_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", 
> scalar.loads_stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", 
> scalar.stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", 
> scalar.general_ops_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", 
> scalar.fp_simd_load_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops", 
> scalar.fp_simd_store_general_ops);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_issue_info_advsimd (const json::object *jo, T &advsimd)
> +parse_vec_costs_issue_info_advsimd (gcc_json_context &ctxt, const 
> json::object &jo, T &advsimd)
>  {
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> advsimd.loads_stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", 
> advsimd.stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> advsimd.general_ops_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> advsimd.fp_simd_load_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> advsimd.fp_simd_store_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops", 
> advsimd.ld2_st2_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops", 
> advsimd.ld3_st3_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops", 
> advsimd.ld4_st4_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", 
> advsimd.loads_stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", 
> advsimd.stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", 
> advsimd.general_ops_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", 
> advsimd.fp_simd_load_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops", 
> advsimd.fp_simd_store_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops", 
> advsimd.ld2_st2_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops", 
> advsimd.ld3_st3_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld4_st4_general_ops", 
> advsimd.ld4_st4_general_ops);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_issue_info_sve (const json::object *jo, T &sve)
> +parse_vec_costs_issue_info_sve (gcc_json_context &ctxt, const json::object 
> &jo, T &sve)
>  {
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> sve.loads_stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", 
> sve.stores_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> sve.general_ops_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> sve.fp_simd_load_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> sve.fp_simd_store_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops", 
> sve.ld2_st2_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops", 
> sve.ld3_st3_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops", 
> sve.ld4_st4_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "pred_ops_per_cycle", 
> sve.pred_ops_per_cycle);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "while_pred_ops", sve.while_pred_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "int_cmp_pred_ops", 
> sve.int_cmp_pred_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_general_ops", 
> sve.gather_scatter_pair_general_ops);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_pred_ops", 
> sve.gather_scatter_pair_pred_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", 
> sve.loads_stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", 
> sve.stores_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", 
> sve.general_ops_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", 
> sve.fp_simd_load_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops", 
> sve.fp_simd_store_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops", 
> sve.ld2_st2_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops", 
> sve.ld3_st3_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld4_st4_general_ops", 
> sve.ld4_st4_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "pred_ops_per_cycle", 
> sve.pred_ops_per_cycle);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "while_pred_ops", 
> sve.while_pred_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "int_cmp_pred_ops", 
> sve.int_cmp_pred_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_cmp_pred_ops", 
> sve.fp_cmp_pred_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_scatter_pair_general_ops", 
> sve.gather_scatter_pair_general_ops);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_scatter_pair_pred_ops", 
> sve.gather_scatter_pair_pred_ops);
>  }
>
>  template <typename T>
>  static void
> -parse_branch_costs (const json::object *jo, T &branch_costs)
> +parse_branch_costs (gcc_json_context &ctxt, const json::object &jo, T 
> &branch_costs)
>  {
> -  PARSE_INTEGER_FIELD (jo, "predictable", branch_costs.predictable);
> -  PARSE_INTEGER_FIELD (jo, "unpredictable", branch_costs.unpredictable);
> -  PARSE_INTEGER_FIELD (jo, "br_mispredict_factor", 
> branch_costs.br_mispredict_factor);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "predictable", branch_costs.predictable);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "unpredictable", 
> branch_costs.unpredictable);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "br_mispredict_factor", 
> branch_costs.br_mispredict_factor);
>  }
>
>  template <typename T>
>  static void
> -parse_approx_modes (const json::object *jo, T &approx_modes)
> +parse_approx_modes (gcc_json_context &ctxt, const json::object &jo, T 
> &approx_modes)
>  {
> -  PARSE_INTEGER_FIELD (jo, "division", approx_modes.division);
> -  PARSE_INTEGER_FIELD (jo, "sqrt", approx_modes.sqrt);
> -  PARSE_INTEGER_FIELD (jo, "recip_sqrt", approx_modes.recip_sqrt);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "division", approx_modes.division);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "sqrt", approx_modes.sqrt);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "recip_sqrt", approx_modes.recip_sqrt);
>  }
>
>  template <typename T>
>  static void
> -parse_memmov_cost (const json::object *jo, T &memmov_cost)
> +parse_memmov_cost (gcc_json_context &ctxt, const json::object &jo, T 
> &memmov_cost)
>  {
> -  PARSE_INTEGER_FIELD (jo, "load_int", memmov_cost.load_int);
> -  PARSE_INTEGER_FIELD (jo, "store_int", memmov_cost.store_int);
> -  PARSE_INTEGER_FIELD (jo, "load_fp", memmov_cost.load_fp);
> -  PARSE_INTEGER_FIELD (jo, "store_fp", memmov_cost.store_fp);
> -  PARSE_INTEGER_FIELD (jo, "load_pred", memmov_cost.load_pred);
> -  PARSE_INTEGER_FIELD (jo, "store_pred", memmov_cost.store_pred);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load_int", memmov_cost.load_int);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_int", memmov_cost.store_int);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load_fp", memmov_cost.load_fp);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_fp", memmov_cost.store_fp);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "load_pred", memmov_cost.load_pred);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "store_pred", memmov_cost.store_pred);
>  }
>
>  template <typename T>
>  static void
> -parse_prefetch (const json::object *jo, T &prefetch)
> +parse_prefetch (gcc_json_context &ctxt, const json::object &jo, T &prefetch)
>  {
> -  PARSE_INTEGER_FIELD (jo, "num_slots", prefetch.num_slots);
> -  PARSE_INTEGER_FIELD (jo, "l1_cache_size", prefetch.l1_cache_size);
> -  PARSE_INTEGER_FIELD (jo, "l1_cache_line_size", 
> prefetch.l1_cache_line_size);
> -  PARSE_INTEGER_FIELD (jo, "l2_cache_size", prefetch.l2_cache_size);
> -  PARSE_BOOLEAN_FIELD (jo, "prefetch_dynamic_strides", 
> prefetch.prefetch_dynamic_strides);
> -  PARSE_INTEGER_FIELD (jo, "minimum_stride", prefetch.minimum_stride);
> -  PARSE_INTEGER_FIELD (jo, "default_opt_level", prefetch.default_opt_level);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "num_slots", prefetch.num_slots);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_size", prefetch.l1_cache_size);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_line_size", 
> prefetch.l1_cache_line_size);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "l2_cache_size", prefetch.l2_cache_size);
> +  PARSE_BOOLEAN_FIELD (ctxt, jo, "prefetch_dynamic_strides", 
> prefetch.prefetch_dynamic_strides);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "minimum_stride", prefetch.minimum_stride);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "default_opt_level", 
> prefetch.default_opt_level);
>  }
>
>  template <typename T>
>  static void
> -parse_insn_extra_cost (const json::object *jo, T &insn_extra_cost)
> +parse_insn_extra_cost (gcc_json_context &ctxt, const json::object &jo, T 
> &insn_extra_cost)
>  {
> -  PARSE_OBJECT (jo, "alu", insn_extra_cost.alu, parse_insn_extra_cost_alu);
> -  PARSE_ARRAY_FIELD (jo, "mult", insn_extra_cost.mult, 
> parse_insn_extra_cost_mult_element);
> -  PARSE_OBJECT (jo, "ldst", insn_extra_cost.ldst, 
> parse_insn_extra_cost_ldst);
> -  PARSE_ARRAY_FIELD (jo, "fp", insn_extra_cost.fp, 
> parse_insn_extra_cost_fp_element);
> -  PARSE_OBJECT (jo, "vect", insn_extra_cost.vect, 
> parse_insn_extra_cost_vect);
> +  PARSE_OBJECT (ctxt, jo, "alu", insn_extra_cost.alu, 
> parse_insn_extra_cost_alu);
> +  PARSE_ARRAY_FIELD (ctxt, jo, "mult", insn_extra_cost.mult, 
> parse_insn_extra_cost_mult_element);
> +  PARSE_OBJECT (ctxt, jo, "ldst", insn_extra_cost.ldst, 
> parse_insn_extra_cost_ldst);
> +  PARSE_ARRAY_FIELD (ctxt, jo, "fp", insn_extra_cost.fp, 
> parse_insn_extra_cost_fp_element);
> +  PARSE_OBJECT (ctxt, jo, "vect", insn_extra_cost.vect, 
> parse_insn_extra_cost_vect);
>  }
>
>  template <typename T>
>  static void
> -parse_addr_cost (const json::object *jo, T &addr_cost)
> +parse_addr_cost (gcc_json_context &ctxt, const json::object &jo, T 
> &addr_cost)
>  {
> -  PARSE_OBJECT (jo, "addr_scale_costs", addr_cost.addr_scale_costs, 
> parse_addr_cost_addr_scale_costs);
> -  PARSE_INTEGER_FIELD (jo, "pre_modify", addr_cost.pre_modify);
> -  PARSE_INTEGER_FIELD (jo, "post_modify", addr_cost.post_modify);
> -  PARSE_INTEGER_FIELD (jo, "post_modify_ld3_st3", 
> addr_cost.post_modify_ld3_st3);
> -  PARSE_INTEGER_FIELD (jo, "post_modify_ld4_st4", 
> addr_cost.post_modify_ld4_st4);
> -  PARSE_INTEGER_FIELD (jo, "register_offset", addr_cost.register_offset);
> -  PARSE_INTEGER_FIELD (jo, "register_sextend", addr_cost.register_sextend);
> -  PARSE_INTEGER_FIELD (jo, "register_zextend", addr_cost.register_zextend);
> -  PARSE_INTEGER_FIELD (jo, "imm_offset", addr_cost.imm_offset);
> +  PARSE_OBJECT (ctxt, jo, "addr_scale_costs", addr_cost.addr_scale_costs, 
> parse_addr_cost_addr_scale_costs);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "pre_modify", addr_cost.pre_modify);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "post_modify", addr_cost.post_modify);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld3_st3", 
> addr_cost.post_modify_ld3_st3);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld4_st4", 
> addr_cost.post_modify_ld4_st4);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "register_offset", 
> addr_cost.register_offset);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "register_sextend", 
> addr_cost.register_sextend);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "register_zextend", 
> addr_cost.register_zextend);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "imm_offset", addr_cost.imm_offset);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs_issue_info (const json::object *jo, T &issue_info)
> +parse_vec_costs_issue_info (gcc_json_context &ctxt, const json::object &jo, 
> T &issue_info)
>  {
> -  PARSE_OBJECT (jo, "scalar", issue_info.scalar, 
> parse_vec_costs_issue_info_scalar);
> -  PARSE_OBJECT (jo, "advsimd", issue_info.advsimd, 
> parse_vec_costs_issue_info_advsimd);
> -  PARSE_OBJECT (jo, "sve", issue_info.sve, parse_vec_costs_issue_info_sve);
> +  PARSE_OBJECT (ctxt, jo, "scalar", issue_info.scalar, 
> parse_vec_costs_issue_info_scalar);
> +  PARSE_OBJECT (ctxt, jo, "advsimd", issue_info.advsimd, 
> parse_vec_costs_issue_info_advsimd);
> +  PARSE_OBJECT (ctxt, jo, "sve", issue_info.sve, 
> parse_vec_costs_issue_info_sve);
>  }
>
>  template <typename T>
>  static void
> -parse_vec_costs (const json::object *jo, T &vec_costs)
> +parse_vec_costs (gcc_json_context &ctxt, const json::object &jo, T 
> &vec_costs)
>  {
> -  PARSE_INTEGER_FIELD (jo, "scalar_int_stmt_cost", 
> vec_costs.scalar_int_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_fp_stmt_cost", 
> vec_costs.scalar_fp_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_load_cost", vec_costs.scalar_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_store_cost", vec_costs.scalar_store_cost);
> -  PARSE_INTEGER_FIELD (jo, "cond_taken_branch_cost", 
> vec_costs.cond_taken_branch_cost);
> -  PARSE_INTEGER_FIELD (jo, "cond_not_taken_branch_cost", 
> vec_costs.cond_not_taken_branch_cost);
> -  PARSE_OBJECT (jo, "advsimd", vec_costs.advsimd, parse_vec_costs_advsimd);
> -  PARSE_OBJECT (jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> -  PARSE_OBJECT (jo, "issue_info", vec_costs.issue_info, 
> parse_vec_costs_issue_info);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scalar_int_stmt_cost", 
> vec_costs.scalar_int_stmt_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scalar_fp_stmt_cost", 
> vec_costs.scalar_fp_stmt_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scalar_load_cost", 
> vec_costs.scalar_load_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "scalar_store_cost", 
> vec_costs.scalar_store_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "cond_taken_branch_cost", 
> vec_costs.cond_taken_branch_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "cond_not_taken_branch_cost", 
> vec_costs.cond_not_taken_branch_cost);
> +  PARSE_OBJECT (ctxt, jo, "advsimd", vec_costs.advsimd, 
> parse_vec_costs_advsimd);
> +  PARSE_OBJECT (ctxt, jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> +  PARSE_OBJECT (ctxt, jo, "issue_info", vec_costs.issue_info, 
> parse_vec_costs_issue_info);
>  }
>
>  template <typename T>
>  static void
> -parse_tunings (const json::object *jo, T &tunings)
> +parse_tunings (gcc_json_context &ctxt, const json::object &jo, T &tunings)
>  {
> -  PARSE_OBJECT (jo, "insn_extra_cost", tunings.insn_extra_cost, 
> parse_insn_extra_cost);
> -  PARSE_OBJECT (jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> -  PARSE_OBJECT (jo, "regmove_cost", tunings.regmove_cost, 
> parse_regmove_cost);
> -  PARSE_OBJECT (jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> -  PARSE_OBJECT (jo, "branch_costs", tunings.branch_costs, 
> parse_branch_costs);
> -  PARSE_OBJECT (jo, "approx_modes", tunings.approx_modes, 
> parse_approx_modes);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "sve_width", tunings.sve_width);
> -  PARSE_OBJECT (jo, "memmov_cost", tunings.memmov_cost, parse_memmov_cost);
> -  PARSE_INTEGER_FIELD (jo, "issue_rate", tunings.issue_rate);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "fusible_ops", tunings.fusible_ops);
> -  PARSE_STRING_FIELD (jo, "function_align", tunings.function_align);
> -  PARSE_STRING_FIELD (jo, "jump_align", tunings.jump_align);
> -  PARSE_STRING_FIELD (jo, "loop_align", tunings.loop_align);
> -  PARSE_INTEGER_FIELD (jo, "int_reassoc_width", tunings.int_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "fp_reassoc_width", tunings.fp_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "fma_reassoc_width", tunings.fma_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "vec_reassoc_width", tunings.vec_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_sf", 
> tunings.min_div_recip_mul_sf);
> -  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_df", 
> tunings.min_div_recip_mul_df);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "max_case_values", 
> tunings.max_case_values);
> -  PARSE_ENUM_FIELD (jo, "autoprefetcher_model", 
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> -  PARSE_UNSIGNED_INTEGER_FIELD (jo, "extra_tuning_flags", 
> tunings.extra_tuning_flags);
> -  PARSE_OBJECT (jo, "prefetch", tunings.prefetch, parse_prefetch);
> -  PARSE_ENUM_FIELD (jo, "ldp_policy_model", tunings.ldp_policy_model, 
> ldp_policy_model_mappings);
> -  PARSE_ENUM_FIELD (jo, "stp_policy_model", tunings.stp_policy_model, 
> stp_policy_model_mappings);
> +  PARSE_OBJECT (ctxt, jo, "insn_extra_cost", tunings.insn_extra_cost, 
> parse_insn_extra_cost);
> +  PARSE_OBJECT (ctxt, jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> +  PARSE_OBJECT (ctxt, jo, "regmove_cost", tunings.regmove_cost, 
> parse_regmove_cost);
> +  PARSE_OBJECT (ctxt, jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> +  PARSE_OBJECT (ctxt, jo, "branch_costs", tunings.branch_costs, 
> parse_branch_costs);
> +  PARSE_OBJECT (ctxt, jo, "approx_modes", tunings.approx_modes, 
> parse_approx_modes);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "sve_width", tunings.sve_width);
> +  PARSE_OBJECT (ctxt, jo, "memmov_cost", tunings.memmov_cost, 
> parse_memmov_cost);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "issue_rate", tunings.issue_rate);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fusible_ops", 
> tunings.fusible_ops);
> +  PARSE_STRING_FIELD (ctxt, jo, "function_align", tunings.function_align);
> +  PARSE_STRING_FIELD (ctxt, jo, "jump_align", tunings.jump_align);
> +  PARSE_STRING_FIELD (ctxt, jo, "loop_align", tunings.loop_align);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "int_reassoc_width", 
> tunings.int_reassoc_width);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fp_reassoc_width", 
> tunings.fp_reassoc_width);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "fma_reassoc_width", 
> tunings.fma_reassoc_width);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "vec_reassoc_width", 
> tunings.vec_reassoc_width);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_sf", 
> tunings.min_div_recip_mul_sf);
> +  PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_df", 
> tunings.min_div_recip_mul_df);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "max_case_values", 
> tunings.max_case_values);
> +  PARSE_ENUM_FIELD (ctxt, jo, "autoprefetcher_model", 
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> +  PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "extra_tuning_flags", 
> tunings.extra_tuning_flags);
> +  PARSE_OBJECT (ctxt, jo, "prefetch", tunings.prefetch, parse_prefetch);
> +  PARSE_ENUM_FIELD (ctxt, jo, "ldp_policy_model", tunings.ldp_policy_model, 
> ldp_policy_model_mappings);
> +  PARSE_ENUM_FIELD (ctxt, jo, "stp_policy_model", tunings.stp_policy_model, 
> stp_policy_model_mappings);
>  }
> \ No newline at end of file
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc 
> b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> index 326d52e02d1ce..40a1cbb41cd71 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> @@ -27,6 +27,7 @@
>  #include "tm.h"
>  #include "diagnostic-core.h"
>  #include "json-parsing.h"
> +#include "json-diagnostic.h"
>  #include "aarch64-json-schema.h"
>  #include "aarch64-json-tunings-parser.h"
>  #include "aarch64-protos.h"
> @@ -34,45 +35,47 @@
>  #include "selftest.h"
>  #include "version.h"
>
> -#define PARSE_INTEGER_FIELD(obj, key, member)                                
>   \
> +#define WARNING_OPT (0)
> +
> +#define PARSE_INTEGER_FIELD(ctxt, obj, key, member)                          
>   \
>    {                                                                          
>   \
> -    const json::value *val = obj->get (key);                                 
>   \
> +    const json::value *val = obj.get (key);                                  
>   \
>      if (val)                                                                 
>   \
> -      member = extract_integer (val);                                        
>   \
> +      member = extract_integer (ctxt, *val, WARNING_OPT);                    
>   \
>    }
>
> -#define PARSE_UNSIGNED_INTEGER_FIELD(obj, key, member)                       
>   \
> +#define PARSE_UNSIGNED_INTEGER_FIELD(ctxt, obj, key, member)                 
>   \
>    {                                                                          
>   \
> -    const json::value *val = obj->get (key);                                 
>   \
> +    const json::value *val = obj.get (key);                                  
>   \
>      if (val)                                                                 
>   \
> -      member = extract_unsigned_integer (val);                               
>   \
> +      member = extract_unsigned_integer (ctxt, *val, WARNING_OPT);           
>   \
>    }
>
> -#define PARSE_BOOLEAN_FIELD(obj, key, member)                                
>   \
> +#define PARSE_BOOLEAN_FIELD(ctxt, obj, key, member)                          
>    \
>    {                                                                          
>   \
> -    const json::value *val = obj->get (key);                                 
>   \
> +    const json::value *val = obj.get (key);                                  
>   \
>      if (val)                                                                 
>   \
> -      member = extract_boolean (val);                                        
>   \
> +      member = extract_boolean (ctxt, *val, WARNING_OPT);                    
>   \
>    }
>
> -#define PARSE_STRING_FIELD(obj, key, member)                                 
>   \
> +#define PARSE_STRING_FIELD(ctxt, obj, key, member)                           
>   \
>    {                                                                          
>   \
> -    const json::value *val = obj->get (key);                                 
>   \
> +    const json::value *val = obj.get (key);                                  
>   \
>      if (val)                                                                 
>   \
> -      member = extract_string (val);                                         
>   \
> +      member = extract_string (ctxt, *val, WARNING_OPT);                     
>   \
>    }
>
> -#define PARSE_OBJECT(obj, key, member, parse_func)                           
>   \
> +#define PARSE_OBJECT(ctxt, obj, key, member, parse_func)                     
>   \
>    {                                                                          
>   \
> -    const json::value *field_value = obj->get (key);                         
>   \
> +    const json::value *field_value = obj.get (key);                          
>   \
>      if (field_value)                                                         
>   \
>        if (auto *field_obj = dyn_cast<const json::object *> (field_value))    
>   \
> -       parse_object_helper (field_obj, (member), (parse_func));              
>  \
> +       parse_object_helper (ctxt, *field_obj, (member), (parse_func));       
>  \
>    }
>
> -#define PARSE_ARRAY_FIELD(obj, key, member, parse_func)                      
>   \
> +#define PARSE_ARRAY_FIELD(ctxt, obj, key, member, parse_func)                
>   \
>    {                                                                          
>   \
> -    const json::value *field_value = obj->get (key);                         
>   \
> +    const json::value *field_value = obj.get (key);                          
>   \
>      if (field_value)                                                         
>   \
>        if (auto *field_array = dyn_cast<const json::array *> (field_value))   
>   \
>         for (size_t i = 0; i < field_array->size (); ++i)                     
>  \
> @@ -80,34 +83,37 @@
>             const json::value *elem = field_array->get (i);                   
>  \
>             if (elem)                                                         
>  \
>               if (auto *array_obj = dyn_cast<const json::object *> (elem))    
>  \
> -               parse_func (array_obj, member[i]);                            
>  \
> +               parse_func (ctxt, *array_obj, member[i]);                     
>  \
>           }                                                                   
>  \
>    }
>
> -#define PARSE_ENUM_FIELD(obj, key, member, mappings)                         
>   \
> -  parse_enum_field (obj, key, member, mappings,                              
>   \
> -                   sizeof (mappings) / sizeof (mappings[0]))
> +#define PARSE_ENUM_FIELD(ctxt, obj, key, member, mappings)                   
>   \
> +  parse_enum_field (ctxt, obj, key, member, mappings,                        
>   \
> +                   sizeof (mappings) / sizeof (mappings[0]), WARNING_OPT)
>
>  /* Type alias for parse function pointer.  */
>  template <typename T>
>  using parse_func_type
> -  = void (*) (const json::object *,
> +  = void (*) (gcc_json_context &,
> +             const json::object &,
>               std::remove_const_t<std::remove_pointer_t<T>> &);
>
>  /* Parse JSON object into non-pointer member type.  */
>  template <typename T>
>  static std::enable_if_t<!std::is_pointer<T>::value>
> -parse_object_helper (const json::object *field_obj, T &member,
> +parse_object_helper (gcc_json_context &ctxt,
> +                    const json::object &field_obj, T &member,
>                      parse_func_type<T> parse_func)
>  {
> -  parse_func (field_obj, member);
> +  parse_func (ctxt, field_obj, member);
>  }
>
>  /* Parse JSON object into a const pointer member by creating a temp copy.  */
>  template <typename T>
>  static std::enable_if_t<std::is_pointer<T>::value
>                         && std::is_const<std::remove_pointer_t<T>>::value>
> -parse_object_helper (const json::object *field_obj, T &member,
> +parse_object_helper (gcc_json_context &ctxt,
> +                    const json::object &field_obj, T &member,
>                      parse_func_type<T> parse_func)
>  {
>    if (!member)
> @@ -120,67 +126,121 @@ parse_object_helper (const json::object *field_obj, T 
> &member,
>    static bool already_initialized = false;
>    if (already_initialized)
>      {
> -      error ("static storage conflict - multiple pointer members of the "
> -            "same type cannot be parsed");
> +      json_error (ctxt, field_obj,
> +                 "static storage conflict - multiple pointer members of "
> +                 "the same type cannot be parsed");
>        return;
>      }
>    already_initialized = true;
>    using NonConstType = std::remove_const_t<std::remove_pointer_t<T>>;
>    static NonConstType new_obj = *member;
> -  parse_func (field_obj, new_obj);
> +  parse_func (ctxt, field_obj, new_obj);
>    member = &new_obj;
>  }
>
> +/* Issue a note about the kind of json value we encountered.  */
> +
> +static void
> +inform_about_wrong_kind_of_json_value (gcc_json_context &ctxt,
> +                                      const json::value &val)
> +{
> +  switch (val.get_kind ())
> +    {
> +    default:
> +      gcc_unreachable ();
> +    case json::JSON_OBJECT:
> +      json_note (ctxt, val, "...but got an object instead");
> +      break;
> +    case json::JSON_ARRAY:
> +      json_note (ctxt, val, "...but got an array instead");
> +      break;
> +    case json::JSON_INTEGER:
> +      json_note (ctxt, val, "...but got an integer instead");
> +      break;
> +    case json::JSON_FLOAT:
> +      json_note (ctxt, val, "...but got a floating-point value instead");
> +      break;
> +    case json::JSON_STRING:
> +      json_note (ctxt, val, "...but got a string instead");
> +      break;
> +    case json::JSON_TRUE:
> +      json_note (ctxt, val, "...but got %qs instead", "true");
> +      break;
> +    case json::JSON_FALSE:
> +      json_note (ctxt, val, "...but got %qs instead", "false");
> +      break;
> +    case json::JSON_NULL:
> +      json_note (ctxt, val, "...but got %qs instead", "null");
> +      break;
> +    }
> +}
> +
>  /* Extract string value from JSON, returning allocated C string.  */
>  char *
> -extract_string (const json::value *val)
> +extract_string (gcc_json_context &ctxt,
> +               const json::value &val,
> +               diagnostics::option_id warning_opt)
>  {
> -  if (auto *string_val = dyn_cast<const json::string *> (val))
> +  if (auto *string_val = dyn_cast<const json::string *> (&val))
>      return xstrdup (string_val->get_string ());
> -  warning (0, "expected a string but got something else or NULL");
> +  auto_diagnostic_group d;
> +  if (json_warning (ctxt, val, warning_opt, "expected a string..."))
> +    inform_about_wrong_kind_of_json_value (ctxt, val);
>    return nullptr;
>  }
>
>  /* Extract signed integer value from JSON.  */
>  int
> -extract_integer (const json::value *val)
> +extract_integer (gcc_json_context &ctxt,
> +                const json::value &val,
> +                diagnostics::option_id warning_opt)
>  {
> -  if (auto *int_val = dyn_cast<const json::integer_number *> (val))
> +  if (auto *int_val = dyn_cast<const json::integer_number *> (&val))
>      {
>        long value = int_val->get ();
>        gcc_assert (value >= INT_MIN && value <= INT_MAX);
>        return static_cast<int> (value);
>      }
> -  warning (0, "expected an integer value but got something else or NULL");
> +  auto_diagnostic_group d;
> +  if (json_warning (ctxt, val, warning_opt, "expected an integer value..."))
> +    inform_about_wrong_kind_of_json_value (ctxt, val);
>    return 0;
>  }
>
>  /* Extract unsigned integer value from JSON.  */
>  unsigned int
> -extract_unsigned_integer (const json::value *val)
> +extract_unsigned_integer (gcc_json_context &ctxt,
> +                         const json::value &val,
> +                         diagnostics::option_id warning_opt)
>  {
> -  if (auto *int_val = dyn_cast<const json::integer_number *> (val))
> +  if (auto *int_val = dyn_cast<const json::integer_number *> (&val))
>      {
>        long value = int_val->get ();
>        gcc_assert (value >= 0 && value <= UINT_MAX);
>        return static_cast<unsigned int> (value);
>      }
> -  warning (0,
> -          "expected an unsigned integer value but got something else or 
> NULL");
> +  auto_diagnostic_group d;
> +  if (json_warning (ctxt, val, warning_opt,
> +                   "expected an unsigned integer value..."))
> +    inform_about_wrong_kind_of_json_value (ctxt, val);
>    return 0;
>  }
>
>  /* Extract boolean value from JSON literal.  */
>  bool
> -extract_boolean (const json::value *val)
> +extract_boolean (gcc_json_context &ctxt,
> +                const json::value &val,
> +                diagnostics::option_id warning_opt)
>  {
> -  if (auto *literal_val = dyn_cast<const json::literal *> (val))
> +  if (auto *literal_val = dyn_cast<const json::literal *> (&val))
>      {
>        json::kind kind = literal_val->get_kind ();
>        if (kind == json::JSON_TRUE || kind == json::JSON_FALSE)
>         return (kind == json::JSON_TRUE);
>      }
> -  warning (0, "expected a boolean value but got something else or NULL");
> +  auto_diagnostic_group d;
> +  if (json_warning (ctxt, val, warning_opt, "expected a boolean value..."))
> +    inform_about_wrong_kind_of_json_value (ctxt, val);
>    return false;
>  }
>
> @@ -193,18 +253,21 @@ template <typename EnumType> struct enum_mapping
>  /* Parse JSON string field into enum value using string-to-enum mappings.  */
>  template <typename EnumType>
>  static void
> -parse_enum_field (const json::object *jo, const std::string &key,
> +parse_enum_field (gcc_json_context &ctxt,
> +                 const json::object &jo, const std::string &key,
>                   EnumType &enum_var, const enum_mapping<EnumType> *mappings,
> -                 size_t num_mappings)
> +                 size_t num_mappings,
> +                 diagnostics::option_id warning_opt)
>  {
> -  const json::value *field_value = jo->get (key.c_str ());
> +  const json::value *field_value = jo.get (key.c_str ());
>    if (!field_value)
>      return;
>
>    auto *string_val = dyn_cast<const json::string *> (field_value);
>    if (!string_val)
>      {
> -      warning (0, "expected string for enum field %s", key.c_str ());
> +      json_warning (ctxt, *field_value, warning_opt,
> +                   "expected string for enum field %s", key.c_str ());
>        enum_var = mappings[0].value;
>        return;
>      }
> @@ -219,8 +282,9 @@ parse_enum_field (const json::object *jo, const 
> std::string &key,
>         }
>      }
>
> -  warning (0, "%s not recognized, defaulting to %qs", key.c_str (),
> -          mappings[0].name);
> +  json_warning (ctxt, *field_value, 0,
> +               "%s not recognized, defaulting to %qs", key.c_str (),
> +               mappings[0].name);
>    enum_var = mappings[0].value;
>  }
>
> @@ -230,7 +294,8 @@ parse_enum_field (const json::object *jo, const 
> std::string &key,
>  /* Validate the user provided JSON data against the present schema.
>     Checks for correct types, fields, and expected format.  */
>  static bool
> -validate_and_traverse (const json::object *json_obj,
> +validate_and_traverse (gcc_json_context &ctxt,
> +                      const json::object *json_obj,
>                        const json::object *schema_obj,
>                        const std::string &parent_key = "")
>  {
> @@ -244,8 +309,9 @@ validate_and_traverse (const json::object *json_obj,
>        const json::value *schema_value = schema_obj->get (key.c_str ());
>        if (!schema_value)
>         {
> -         warning (0, "key %qs is not a tuning parameter, skipping",
> -                  full_key.c_str ());
> +         json_warning (ctxt, *json_value, WARNING_OPT,
> +                       "key %qs is not a tuning parameter, skipping",
> +                       full_key.c_str ());
>           continue;
>         }
>
> @@ -253,13 +319,15 @@ validate_and_traverse (const json::object *json_obj,
>         {
>           if (auto *sub_json_obj = dyn_cast<const json::object *> 
> (json_value))
>             {
> -             if (!validate_and_traverse (sub_json_obj, sub_schema_obj,
> +             if (!validate_and_traverse (ctxt, sub_json_obj, sub_schema_obj,
>                                           full_key))
>                 return false;
>             }
>           else
>             {
> -             error ("key %qs expected to be an object", full_key.c_str ());
> +             json_error (ctxt, *json_value,
> +                         "key %qs expected to be an object",
> +                         full_key.c_str ());
>               return false;
>             }
>         }
> @@ -267,7 +335,8 @@ validate_and_traverse (const json::object *json_obj,
>         {
>           if (json_value->get_kind () != json::JSON_ARRAY)
>             {
> -             error ("key %qs expected to be an array", full_key.c_str ());
> +             json_error (ctxt, *json_value,
> +                         "key %qs expected to be an array", full_key.c_str 
> ());
>               return false;
>             }
>         }
> @@ -280,8 +349,9 @@ validate_and_traverse (const json::object *json_obj,
>             {
>               if (json_value->get_kind () != json::JSON_INTEGER)
>                 {
> -                 error ("key %qs expected to be an integer",
> -                        full_key.c_str ());
> +                 json_error (ctxt, *json_value,
> +                             "key %qs expected to be an integer",
> +                             full_key.c_str ());
>                   return false;
>                 }
>               // Check if the value is valid for signed integer
> @@ -291,9 +361,10 @@ validate_and_traverse (const json::object *json_obj,
>                   long value = int_val->get ();
>                   if (value > INT_MAX || value < INT_MIN)
>                     {
> -                     error ("key %qs value %ld is out of range for %<int%> "
> -                            "type [%d, %d]",
> -                            full_key.c_str (), value, INT_MIN, INT_MAX);
> +                     json_error (ctxt, *json_value,
> +                                 "key %qs value %ld is out of range for "
> +                                 "%<int%> type [%d, %d]",
> +                                 full_key.c_str (), value, INT_MIN, INT_MAX);
>                       return false;
>                     }
>                 }
> @@ -302,8 +373,9 @@ validate_and_traverse (const json::object *json_obj,
>             {
>               if (json_value->get_kind () != json::JSON_INTEGER)
>                 {
> -                 error ("key %qs expected to be an unsigned integer",
> -                        full_key.c_str ());
> +                 json_error (ctxt, *json_value,
> +                             "key %qs expected to be an unsigned integer",
> +                             full_key.c_str ());
>                   return false;
>                 }
>               // Check if the value is valid for unsigned integer
> @@ -313,9 +385,10 @@ validate_and_traverse (const json::object *json_obj,
>                   long value = int_val->get ();
>                   if (value < 0 || value > UINT_MAX)
>                     {
> -                     error ("key %qs value %ld is out of range for %<uint%> "
> -                            "type [0, %u]",
> -                            full_key.c_str (), value, UINT_MAX);
> +                     json_error (ctxt, *json_value,
> +                                 "key %qs value %ld is out of range for "
> +                                 "%<uint%> type [0, %u]",
> +                                 full_key.c_str (), value, UINT_MAX);
>                       return false;
>                     }
>                 }
> @@ -324,7 +397,9 @@ validate_and_traverse (const json::object *json_obj,
>             {
>               if (json_value->get_kind () != json::JSON_STRING)
>                 {
> -                 error ("key %qs expected to be a string", full_key.c_str 
> ());
> +                 json_error (ctxt, *json_value,
> +                             "key %qs expected to be a string",
> +                             full_key.c_str ());
>                   return false;
>                 }
>             }
> @@ -333,8 +408,9 @@ validate_and_traverse (const json::object *json_obj,
>               if (json_value->get_kind () != json::JSON_TRUE
>                   && json_value->get_kind () != json::JSON_FALSE)
>                 {
> -                 error ("key %qs expected to be a boolean (true/false)",
> -                        full_key.c_str ());
> +                 json_error (ctxt, *json_value,
> +                             "key %qs expected to be a boolean (true/false)",
> +                             full_key.c_str ());
>                   return false;
>                 }
>             }
> @@ -342,20 +418,24 @@ validate_and_traverse (const json::object *json_obj,
>             {
>               if (json_value->get_kind () != json::JSON_STRING)
>                 {
> -                 error ("key %qs expected to be an enum (string)",
> -                        full_key.c_str ());
> +                 json_error (ctxt, *json_value,
> +                             "key %qs expected to be an enum (string)",
> +                             full_key.c_str ());
>                   return false;
>                 }
>             }
>           else
>             {
> -             error ("key %qs has unsupported type", full_key.c_str ());
> +             json_error (ctxt, *json_value,
> +                         "key %qs has unsupported type", full_key.c_str ());
>               return false;
>             }
>         }
>        else
>         {
> -         error ("key %qs has unexpected format in schema", full_key.c_str 
> ());
> +         json_error (ctxt, *json_value,
> +                     "key %qs has unexpected format in schema",
> +                     full_key.c_str ());
>           return false;
>         }
>      }
> @@ -413,13 +493,15 @@ check_version_compatibility (const json::object 
> *root_obj)
>
>    if (json_gcc_major_version == -1)
>      {
> -      warning (0, "JSON tuning file does not contain version information; "
> -                 "compatibility cannot be verified");
> +      warning (WARNING_OPT,
> +              "JSON tuning file does not contain version information; "
> +              "compatibility cannot be verified");
>        return true;
>      }
>
>    if (json_gcc_major_version != GCC_major_version)
>      {
> +      auto_diagnostic_group d;
>        error ("JSON tuning file was created with GCC version %d "
>              "but current GCC version is %d",
>              json_gcc_major_version, GCC_major_version);
> @@ -433,31 +515,32 @@ check_version_compatibility (const json::object 
> *root_obj)
>
>  /* Main routine for setting up the parsing of JSON data.  */
>  static void
> -aarch64_load_tuning_params_from_json_string (const char *json_string,
> +aarch64_load_tuning_params_from_json_string (const char *js_filename,
> +                                            const char *json_string,
>                                              const char *schema_string,
>                                              struct tune_params *tune)
>  {
>    /* Try parsing the JSON string.  */
> +  gcc_json_context ctxt (js_filename);
>    json::parser_result_t data_result
>      = json::parse_utf8_string (strlen (json_string), json_string, true,
> -                              nullptr);
> +                              &ctxt);
>
>    if (auto json_err = data_result.m_err.get ())
>      {
> -      error ("error parsing JSON data: %s", json_err->get_msg ());
> +      location_t js_loc = ctxt.make_location_for_range (json_err->get_range 
> ());
> +      error_at (js_loc, "error parsing JSON data: %s", json_err->get_msg ());
>        return;
>      }
>
> -  const std::unique_ptr<json::value> &root = data_result.m_val;
> -  if (!root)
> -    {
> -      error ("JSON parsing returned null data");
> -      return;
> -    }
> -  auto *root_obj = dyn_cast<const json::object *> (root.get ());
> +  const json::value* root = data_result.m_val.get ();
> +  gcc_assert (root);
> +
> +  auto *root_obj = dyn_cast<const json::object *> (root);
>    if (!root_obj)
>      {
> -      warning (0, "no JSON object found in the provided data");
> +      json_warning (ctxt, *root, WARNING_OPT,
> +                   "no JSON object found in the provided data");
>        return;
>      }
>
> @@ -479,24 +562,26 @@ aarch64_load_tuning_params_from_json_string (const char 
> *json_string,
>    const json::value *tune_params_value = root_obj->get ("tune_params");
>    if (!tune_params_value)
>      {
> -      warning (0, "key %<tune_params%> not found in JSON data");
> +      json_warning (ctxt, *root_obj, WARNING_OPT,
> +                   "key %<tune_params%> not found in JSON data");
>        return;
>      }
>
>    auto *jo = dyn_cast<const json::object *> (tune_params_value);
>    if (!jo)
>      {
> -      error ("key %<tune_params%> is not a JSON object");
> +      json_error (ctxt, *tune_params_value,
> +                 "key %<tune_params%> is not a JSON object");
>        return;
>      }
>
> -  if (!validate_and_traverse (root_obj, schema_obj))
> +  if (!validate_and_traverse (ctxt, root_obj, schema_obj))
>      {
>        error ("validation failed for the provided JSON data");
>        return;
>      }
>
> -  parse_tunings (jo, *tune);
> +  parse_tunings (ctxt, *jo, *tune);
>    return;
>  }
>
> @@ -511,8 +596,9 @@ aarch64_load_tuning_params_from_json (const char 
> *data_filename,
>        error ("cannot read JSON data in %s", data_filename);
>        return;
>      }
> -  aarch64_load_tuning_params_from_json_string (
> -    (const char *) json_data->data (), schema_json, tune);
> +  aarch64_load_tuning_params_from_json_string
> +    (data_filename,
> +     (const char *) json_data->data (), schema_json, tune);
>  }
>
>  #if CHECKING_P
> @@ -536,7 +622,8 @@ test_json_integers ()
>
>    tune_params params;
>
> -  aarch64_load_tuning_params_from_json_string (test_json, schema_json, 
> &params);
> +  aarch64_load_tuning_params_from_json_string
> +    ("test.json", test_json, schema_json, &params);
>
>    ASSERT_EQ (params.sve_width, 256);
>    ASSERT_EQ (params.issue_rate, 4);
> @@ -563,7 +650,8 @@ test_json_boolean ()
>    tune_params params;
>    params.insn_extra_cost = &default_cost_table;
>
> -  aarch64_load_tuning_params_from_json_string (test_json, schema_json, 
> &params);
> +  aarch64_load_tuning_params_from_json_string
> +    ("test.json", test_json, schema_json, &params);
>
>    ASSERT_EQ (params.insn_extra_cost->alu.non_exec_costs_exec, false);
>  }
> @@ -584,7 +672,8 @@ test_json_strings ()
>
>    tune_params params;
>
> -  aarch64_load_tuning_params_from_json_string (test_json, schema_json, 
> &params);
> +  aarch64_load_tuning_params_from_json_string
> +    ("test.json", test_json, schema_json, &params);
>
>    ASSERT_STREQ (params.function_align, "16");
>    ASSERT_STREQ (params.jump_align, "2");
> @@ -607,7 +696,8 @@ test_json_enums ()
>
>    tune_params params;
>
> -  aarch64_load_tuning_params_from_json_string (test_json, schema_json, 
> &params);
> +  aarch64_load_tuning_params_from_json_string
> +    ("test.json", test_json, schema_json, &params);
>
>    ASSERT_EQ (params.autoprefetcher_model, tune_params::AUTOPREFETCHER_OFF);
>    ASSERT_EQ (params.ldp_policy_model, AARCH64_LDP_STP_POLICY_NEVER);
> diff --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
> index aef632f1d0423..0ed8f71b775d0 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> @@ -1,8 +1,16 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-2.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be a boolean"  "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json: In 
> JSON value '/tune_params/insn_extra_cost/alu/non_exec_costs_exec'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json:5:32: error: key .* 
> expected to be a boolean \\\(true/false\\\)"  } */
> +/* { dg-begin-multiline-output "" }
> +    5 |         "non_exec_costs_exec": 0
> +      |                                ^
> +   { dg-end-multiline-output "" } */
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --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
> index 4df72dbaf7ab4..cbbe8afe760ec 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> @@ -1,7 +1,12 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-warning "key 'tune_params' not found in JSON data"  "" { target 
> *-*-* } 0 } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json:1:1: warning: 
> key 'tune_params' not found in JSON data" } */
> +/* { dg-begin-multiline-output "" }
> +    1 | {}
> +      | ^~
> +   { dg-end-multiline-output "" } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --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
> index c53bc5292d52f..30e0fd47d7946 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> @@ -1,8 +1,21 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-2.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-warning "autoprefetcher_model not recognized, defaulting to 
> 'AUTOPREFETCHER_OFF'"  "" { target *-*-* } 0 } */
> -/* { dg-warning "ldp_policy_model not recognized, defaulting to 
> 'AARCH64_LDP_STP_POLICY_DEFAULT'"  "" { target *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In 
> JSON value '/tune_params/autoprefetcher_model'" } */
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:3:29: 
> warning: autoprefetcher_model not recognized, defaulting to 
> 'AUTOPREFETCHER_OFF'" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "autoprefetcher_model": "null",
> +      |                             ^~~~~~
> +   { dg-end-multiline-output "" } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In 
> JSON value '/tune_params/ldp_policy_model'" } */
> +/* { 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'" } */
> +/* { dg-begin-multiline-output "" }
> +    4 |     "ldp_policy_model": "null",
> +      |                         ^~~~~~
> +   { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --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
> index 093c86048ce95..4e9de75a7aa7d 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> @@ -1,8 +1,16 @@
>  /* { dg-do compile } */
> -/* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json
>  -fdump-tuning-model=temp.json " } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'int' type"  "" { target 
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json: In 
> JSON value '/tune_params/int_reassoc_width'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json:3:26: error: key .* 
> value .* is out of range for 'int' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "int_reassoc_width": 12097307449014
> +      |                          ^~~~~~~~~~~~~~
> +   { dg-end-multiline-output "" } */
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --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
> index 438685c6002c6..bab713b35d03f 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> @@ -1,8 +1,17 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-3.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be an integer"  "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json: In 
> JSON value '/tune_params/issue_rate'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json:3:19: error: key .* 
> expected to be an integer" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "issue_rate": "10"
> +      |                   ^~~~
> +   { dg-end-multiline-output "" } */
> +
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c 
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> new file mode 100644
> index 0000000000000..f4d6bc0a1376c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/malformed.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
> +
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/malformed.json:3:17: error: error 
> parsing JSON data: expected ':'; got number" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "sve_width" 128
> +      |                 ^~~
> +   { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json 
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> new file mode 100644
> index 0000000000000..541b721faccde
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> @@ -0,0 +1,5 @@
> +{
> +  "tune_params": {
> +    "sve_width" 128
> +  }
> +}
> diff --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
> index ad3ea1422bade..ae6e265c514ac 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> @@ -1,8 +1,16 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-2.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be a string"  "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json: In 
> JSON value '/tune_params/function_align'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json:3:23: error: key .* 
> expected to be a string"  "" { target *-*-* } 0 } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "function_align": 16
> +      |                       ^~
> +   { dg-end-multiline-output "" } */
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --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
> index bafbda8a1ef57..27bfacc40203d 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> @@ -1,7 +1,15 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-warning "key .* is not a tuning parameter, skipping"  "" { target 
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json: In JSON 
> value '/tune_params/unidentified_key'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json:3:25: 
> warning: key .* is not a tuning parameter, skipping"  "" { target *-*-* } 0 } 
> */
> +
> +/* { dg-begin-multiline-output "" }
> +    3 |     "unidentified_key": "10"
> +      |                         ^~~~
> +   { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --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
> index ce1989d8e31df..88848e406cc0a 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> @@ -1,8 +1,16 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'uint' type"  "" { target 
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json: 
> In JSON value '/tune_params/sve_width'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json:3:18: error: key 
> .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "sve_width": -128,
> +      |                  ^~~~
> +   { dg-end-multiline-output "" } */
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
>  int main () {}
> diff --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
> index 20a661f557026..0e808009810ef 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> @@ -1,8 +1,16 @@
>  /* { dg-do compile } */
>  /* { dg-additional-options 
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json
>  -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret 
> -fdiagnostics-show-line-numbers" } */
>
>  /* { dg-warning "JSON tuning file does not contain version information" "" { 
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'uint' type"  "" { target 
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json: 
> In JSON value '/tune_params/sve_width'" } */
> +/* { dg-regexp 
> ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json:3:18: error: key 
> .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> +    3 |     "sve_width": 5000000000
> +      |                  ^~~~~~~~~~
> +   { dg-end-multiline-output "" } */
> +
>  /* { dg-error "validation failed for the provided JSON data"  "" { target 
> *-*-* } 0 } */
>
>  int main () {}
> --
> 2.26.3
>

Reply via email to