https://gcc.gnu.org/g:a9b17a06b23de1fdc9f39e63bcb32a3397e81e49

commit r16-6624-ga9b17a06b23de1fdc9f39e63bcb32a3397e81e49
Author: Viljar Indus <[email protected]>
Date:   Tue Nov 25 14:45:29 2025 +0200

    ada: Add support for printing switches in the SARIF report
    
    Previously the report for all of the available diagnostics
    and switches was given in a custom JSON format. This patch
    merges the two reports and includes them in a special SARIF
    report where all of the diagnostics and switches are presented
    as switches in the rules section of the report. Switches and
    diagnostics are linked with each other through the relationship
    node. Diagnostic rules will have a superset relation to a switch
    rule and a Switch rule will have a subset relation to each of its
    diagnostic rules.
    
    In order to facilitate those changes the errid and errsw packages were
    reorganized. Now errid will have the definitions for both all of the
    Diagnostic_Id-s and Switch_Id-s. The two new subpackages for errid -
    Diagnostic_Repository and Switch_Repository will hold the repository
    information that will be presented in the SARIF report.
    
    gcc/ada/ChangeLog:
    
            * errid-diagnostic_repository.ads: New package for storing
            information about diagnostics.
            * errid-switch_repository.adb: New package for storing
            information about switches.
            * errid-switch_repository.ads: Likewise.
            * errid.adb: Move common methods related to Diagnostic_Id-s and
            Switch_Id-s to this pacakge.
            * errid.ads: Likewise.
            * errout.adb (Add_Unique_Diagnostics_And_Switches): New method
            for gathering all of the unique Diagnostic_Id-s and Switch_Id-s
            among all of the error messages.
            (Output_Messages): Use the new SARIF printer interface for printing
            the report.
            * erroutc-sarif_emitter.adb (Print_Relationship): New method for
            printing relationship nodes.
            (Print_Rule): Support printing switches as rules. Add support
            for printing relationship nodes under rules. Remove brackets around
            the rule name.
            (Print_Runs): Add a printer argument to pass all of the switches
            and diagnostics as rules in the SARIF report.
            (Print_Tool): Likewise.
            (Free): New method.
            (Get_Unique_Rules): Removed.
            (Print_Result): Remove brackets around the rule name.
            (Print_Rules): Print switches as rules.
            * erroutc-sarif_emitter.ads (SARIF_Printer): New record type for
            storing and passing all of the diagnostic and switch information
            around in the SARIF printer.
            (Report_Kind): New type for indicating the different reports the
            SARIF emitter can produce.
            (Free): New method for releasing all of the dynamically allocated
            memory.
            (Print_SARIF_Report): Add a SARIF_Printer argument.
            * erroutc.adb (Get_Human_Id): Removed.
            (Get_Switch): Removed.
            (Get_Doc_Switch): Simplify code.
            * erroutc.ads: (Get_Human_Id): Removed.
            (Get_Switch): Removed.
            * errsw.adb: Replaced by errid-switch_repository.adb.
            * errsw.ads: Replaced by errid-switch_repository.ads.
            * errutil.adb: Remove dependecy to errsw pacakge.
            * par-endh.adb: Fix whitespace.
            * gcc-interface/Make-lang.in: Update the dependencies.
            * gcc-interface/Makefile.in: Likewise.

Diff:
---
 gcc/ada/errid-diagnostic_repository.ads            |  86 +++
 gcc/ada/errid-switch_repository.adb                |  46 ++
 gcc/ada/{errsw.adb => errid-switch_repository.ads} | 609 ++++++++++-----------
 gcc/ada/errid.adb                                  | 134 ++---
 gcc/ada/errid.ads                                  | 166 +++---
 gcc/ada/errout.adb                                 | 125 ++++-
 gcc/ada/erroutc-sarif_emitter.adb                  | 305 +++++++----
 gcc/ada/erroutc-sarif_emitter.ads                  |  52 +-
 gcc/ada/erroutc.adb                                |  29 +-
 gcc/ada/erroutc.ads                                |   8 -
 gcc/ada/errsw.ads                                  | 155 ------
 gcc/ada/errutil.adb                                |   1 -
 gcc/ada/gcc-interface/Make-lang.in                 |   6 +-
 gcc/ada/gcc-interface/Makefile.in                  |   3 +-
 gcc/ada/par-endh.adb                               |   2 +-
 15 files changed, 943 insertions(+), 784 deletions(-)

diff --git a/gcc/ada/errid-diagnostic_repository.ads 
b/gcc/ada/errid-diagnostic_repository.ads
new file mode 100644
index 000000000000..b81911211361
--- /dev/null
+++ b/gcc/ada/errid-diagnostic_repository.ads
@@ -0,0 +1,86 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--           E R R I D . D I A G N O S T I C _ R E P O S I T O R Y          --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--          Copyright (C) 1992-2025, Free Software Foundation, Inc.         --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
+-- for  more details.  You should have  received  a copy of the GNU General --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Types; use Types;
+
+package Errid.Diagnostic_Repository is
+   type Diagnostic_Entry_Type is record
+      Status : Status_Type := Active;
+
+      Human_Id : String_Ptr := null;
+      --  A human readable code for the diagnostic. If the diagnostic has a
+      --  switch with a human id then the human_id of the switch shall be used
+      --  in SARIF reports.
+
+      Switch : Switch_Id := No_Switch_Id;
+      --  The switch that controls the diagnostic message.
+   end record;
+
+   type Diagnostics_Registry_Type is
+     array (Diagnostic_Id) of Diagnostic_Entry_Type;
+
+   --  Include the diagnostic entries for every diagnostic id.
+   --  The entries should include:
+   --  * Whether the diagnostic with this id is active or not
+   --  * The human-readable name for the diagnostic for SARIF reports
+   --  * The switch id for the diagnostic if the diagnostic is linked to any
+   --    compiler switch
+   --  * The documentation file for the diagnostic written in the MD format.
+   --    The documentation file should include:
+   --    - The diagnostic id
+   --    - A short description of the diagnostic
+   --    - A minimal example of the code that triggers the diagnostic
+   --    - An explanation of why the diagnostic was triggered
+   --    - A suggestion on how to fix the issue
+   --    - Optionally additional information
+   --    TODO: the mandatory fields for the documentation file could be changed
+
+   Diagnostic_Entries : constant Diagnostics_Registry_Type :=
+     (No_Diagnostic_Id => <>,
+      GNAT0001         =>
+        (Status   => Active,
+         Human_Id => new String'("Default_Iterator_Not_Primitive_Error"),
+         Switch   => No_Switch_Id),
+      GNAT0002         =>
+        (Status   => Active,
+         Human_Id => new String'("Invalid_Operand_Types_General_Error"),
+         Switch   => No_Switch_Id),
+      GNAT0003         =>
+        (Status   => Active,
+         Human_Id => new String'("Pragma_No_Effect_With_Lock_Free_Warning"),
+         Switch   => No_Switch_Id),
+      GNAT0004         =>
+        (Status   => Active,
+         Human_Id => new String'("End_Loop_Expected_Error"),
+         Switch   => No_Switch_Id),
+      GNAT0005         =>
+        (Status   => Active,
+         Human_Id => new String'("Representation_Too_Late_Error"),
+         Switch   => No_Switch_Id),
+      GNAT0006         =>
+        (Status   => Active,
+         Human_Id => new String'("Mixed_Container_Aggregate_Error"),
+         Switch   => No_Switch_Id));
+end Errid.Diagnostic_Repository;
diff --git a/gcc/ada/errid-switch_repository.adb 
b/gcc/ada/errid-switch_repository.adb
new file mode 100644
index 000000000000..c81a7e13d721
--- /dev/null
+++ b/gcc/ada/errid-switch_repository.adb
@@ -0,0 +1,46 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--               E R R I D . S W I T C H _ R E P O S I T O R Y              --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--          Copyright (C) 1992-2025, Free Software Foundation, Inc.         --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
+-- for  more details.  You should have  received  a copy of the GNU General --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+package body Errid.Switch_Repository is
+
+   -------------------
+   -- Get_Switch_Id --
+   -------------------
+
+   function Get_Switch_Id (Name : String) return Switch_Id is
+      Trimmed_Name : constant String :=
+        (if Name (Name'Last) = ' ' then Name (Name'First .. Name'Last - 1)
+         else Name);
+   begin
+      for I in Active_Switch_Id loop
+         if Switches (I).Short_Name.all = Trimmed_Name then
+            return I;
+         end if;
+      end loop;
+
+      return No_Switch_Id;
+   end Get_Switch_Id;
+
+end Errid.Switch_Repository;
diff --git a/gcc/ada/errsw.adb b/gcc/ada/errid-switch_repository.ads
similarity index 63%
rename from gcc/ada/errsw.adb
rename to gcc/ada/errid-switch_repository.ads
index 1edc8cd615b2..73e23588882f 100644
--- a/gcc/ada/errsw.adb
+++ b/gcc/ada/errid-switch_repository.ads
@@ -2,9 +2,9 @@
 --                                                                          --
 --                         GNAT COMPILER COMPONENTS                         --
 --                                                                          --
---                                E R R S W                                 --
+--               E R R I D . S W I T C H _ R E P O S I T O R Y              --
 --                                                                          --
---                                 B o d y                                  --
+--                                 S p e c                                  --
 --                                                                          --
 --          Copyright (C) 1992-2025, Free Software Foundation, Inc.         --
 --                                                                          --
@@ -23,644 +23,643 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with JSON_Utils; use JSON_Utils;
-with Output;     use Output;
+with Types; use Types;
 
-package body Errsw is
+package Errid.Switch_Repository is
 
-   Switches : constant array (Switch_Id)
-     of Switch_Type :=
-     (No_Switch_Id            =>
-        <>,
-      gnatwb                  =>
+   type Switch_Type is record
+
+      Status : Status_Type := Active;
+      --  The status will indicate whether the switch is currently active,
+      --  or has been deprecated. A deprecated switch will not control
+      --  diagnostics, and will not be emitted by the GNAT usage.
+
+      Human_Id : String_Ptr := null;
+      --  The Human_Id will be a unique and stable string-based ID which
+      --  identifies the content of the switch within the switch registry.
+      --  This ID will appear in SARIF readers.
+
+      Short_Name : String_Ptr := null;
+      --  The Short_Name will denote the -gnatXX name of the switch.
+
+      Description : String_Ptr := null;
+      --  The description will contain the description of the switch, as it is
+      --  currently emitted by the GNAT usage.
+
+      Documentation_Url : String_Ptr := null;
+      --  The documentation_url will point to the AdaCore documentation site
+      --  for the switch.
+
+      Diagnostics : Diagnostic_Id_Array_Access := null;
+      --  Diagnostics that are activated by the given switch.
+
+   end record;
+
+   Switches : constant array (Switch_Id) of Switch_Type :=
+     (No_Switch_Id       => <>,
+      gnatwb             =>
         (Human_Id          => new String'("Warn_On_Bad_Fixed_Value"),
          Status            => Active,
          Short_Name        => new String'("gnatwb"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwc                  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwc             =>
         (Human_Id          => new String'("Constant_Condition_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatwc"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwd                  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwd             =>
         --  TODO: is this a subcheck of general gnatwu?
         (Human_Id          => new String'("Warn_On_Dereference"),
          Status            => Active,
          Short_Name        => new String'("gnatwd"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwf                       =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwf             =>
         (Human_Id          => new String'("Check_Unreferenced_Formals"),
          Status            => Active,
          Short_Name        => new String'("gnatwf"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwg                       =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwg             =>
         (Human_Id          => new String'("Warn_On_Unrecognized_Pragma"),
          Status            => Active,
          Short_Name        => new String'("gnatwg"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwh                       =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwh             =>
         (Human_Id          => new String'("Warn_On_Hiding"),
          Status            => Active,
          Short_Name        => new String'("gnatwh"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwi                       =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwi             =>
         (Human_Id          => new String'("Implementation_Unit_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatwi"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwj                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwj             =>
         (Human_Id          => new String'("Warn_On_Obsolescent_Feature"),
          Status            => Active,
          Short_Name        => new String'("gnatwj"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwk                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwk             =>
         (Human_Id          => new String'("Warn_On_Constant"),
          Status            => Active,
          Short_Name        => new String'("gnatwk"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwl                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwl             =>
         (Human_Id          => new String'("Elab_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatwl"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwm                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwm             =>
         (Human_Id          => new String'("Warn_On_Modified_Unread"),
          Status            => Active,
          Short_Name        => new String'("gnatwm"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwo                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwo             =>
         (Human_Id          => new String'("Address_Clause_Overlay_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatwo"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwp                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwp             =>
         (Human_Id          => new String'("Ineffective_Inline_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatwp"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwq                      =>
-        (Human_Id => new String'("Warn_On_Questionable_Missing_Parens"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwq             =>
+        (Human_Id          =>
+           new String'("Warn_On_Questionable_Missing_Parens"),
          Status            => Active,
          Short_Name        => new String'("gnatwq"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwr                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwr             =>
         (Human_Id          => new String'("Warn_On_Redundant_Constructs"),
          Status            => Active,
          Short_Name        => new String'("gnatwr"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwt                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwt             =>
         (Human_Id          => new String'("Warn_On_Deleted_Code"),
          Status            => Active,
          Short_Name        => new String'("gnatwt"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwu                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwu             =>
         (Human_Id          => new String'("Warn_On_Unused_Entities"),
          Status            => Active,
          Short_Name        => new String'("gnatwu"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwv                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwv             =>
         (Human_Id          => new String'("Warn_On_No_Value_Assigned"),
          Status            => Active,
          Short_Name        => new String'("gnatwv"),
          Description       => null,
-         Documentation_Url => null),
-      gnatww                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatww             =>
         (Human_Id          => new String'("Warn_On_Assumed_Low_Bound"),
          Status            => Active,
          Short_Name        => new String'("gnatww"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwx                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwx             =>
         (Human_Id          => new String'("Warn_On_Export_Import"),
          Status            => Active,
          Short_Name        => new String'("gnatwx"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwy                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwy             =>
         (Human_Id          => new String'("Warn_On_Ada_Compatibility_Issues"),
          Status            => Active,
          Short_Name        => new String'("gnatwy"),
          Description       => null,
-         Documentation_Url => null),
-      gnatwz                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatwz             =>
         (Human_Id          => new String'("Warn_On_Unchecked_Conversion"),
          Status            => Active,
          Short_Name        => new String'("gnatwz"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_a                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_a        =>
         (Human_Id          => new String'("Warn_On_Assertion_Failure"),
          Status            => Active,
          Short_Name        => new String'("gnatw.a"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_b                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_b        =>
         (Human_Id          => new String'("Warn_On_Biased_Representation"),
          Status            => Active,
          Short_Name        => new String'("gnatw.b"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_c                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_c        =>
         (Human_Id          => new String'("Warn_On_Unrepped_Components"),
          Status            => Active,
          Short_Name        => new String'("gnatw.c"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_f                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_f        =>
         (Human_Id          => new String'("Warn_On_Elab_Access"),
          Status            => Active,
          Short_Name        => new String'("gnatw.f"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_h                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_h        =>
         (Human_Id          => new String'("Warn_On_Record_Holes"),
          Status            => Active,
          Short_Name        => new String'("gnatw.h"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_i                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_i        =>
         (Human_Id          => new String'("Warn_On_Overlap"),
          Status            => Active,
          Short_Name        => new String'("gnatw.i"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_j                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_j        =>
         (Human_Id          => new String'("Warn_On_Late_Primitives"),
          Status            => Active,
          Short_Name        => new String'("gnatw.j"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_k                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_k        =>
         (Human_Id          => new String'("Warn_On_Standard_Redefinition"),
          Status            => Active,
          Short_Name        => new String'("gnatw.k"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_l                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_l        =>
         (Human_Id          => new String'("List_Inherited_Aspects"),
          Status            => Active,
          Short_Name        => new String'("gnatw.l"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_m                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_m        =>
         (Human_Id          => new String'("Warn_On_Suspicious_Modulus_Value"),
          Status            => Active,
          Short_Name        => new String'("gnatw.m"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_n                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_n        =>
         (Human_Id          => new String'("Warn_On_Atomic_Synchronization"),
          Status            => Active,
          Short_Name        => new String'("gnatw.n"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_o                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_o        =>
         (Human_Id          => new String'("Warn_On_All_Unread_Out_Parameters"),
          Status            => Active,
          Short_Name        => new String'("gnatw.o"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_p                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_p        =>
         (Human_Id          => new String'("Warn_On_Parameter_Order"),
          Status            => Active,
          Short_Name        => new String'("gnatw.p"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_q                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_q        =>
         (Human_Id          => new String'("Warn_On_Questionable_Layout"),
          Status            => Active,
          Short_Name        => new String'("gnatw.q"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_r                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_r        =>
         (Human_Id          => new String'("Warn_On_Object_Renames_Function"),
          Status            => Active,
          Short_Name        => new String'("gnatw.r"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_s                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_s        =>
         (Human_Id          => new String'("Warn_On_Overridden_Size"),
          Status            => Active,
          Short_Name        => new String'("gnatw.s"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_t                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_t        =>
         (Human_Id          => new String'("Warn_On_Suspicious_Contract"),
          Status            => Active,
          Short_Name        => new String'("gnatw.t"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_u                      =>
-        (Human_Id => new String'("Warn_On_Unordered_Enumeration_Type"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_u        =>
+        (Human_Id          =>
+           new String'("Warn_On_Unordered_Enumeration_Type"),
          Status            => Active,
          Short_Name        => new String'("gnatw.u"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_v                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_v        =>
         (Human_Id          => new String'("Warn_On_Reverse_Bit_Order"),
          Status            => Active,
          Short_Name        => new String'("gnatw.v"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_w                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_w        =>
         (Human_Id          => new String'("Warn_On_Warnings_Off"),
          Status            => Active,
          Short_Name        => new String'("gnatw.w"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_x                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_x        =>
         (Human_Id          =>
-          new String'("Warn_No_Exception_Propagation_Active"),
+           new String'("Warn_No_Exception_Propagation_Active"),
          Status            => Active,
          Short_Name        => new String'("gnatw.x"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_y                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_y        =>
         (Human_Id          => new String'("List_Body_Required_Info"),
          Status            => Active,
          Short_Name        => new String'("gnatw.y"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_dot_z                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_dot_z        =>
         (Human_Id          => new String'("Warn_On_Size_Alignment"),
          Status            => Active,
          Short_Name        => new String'("gnatw.z"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_a                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_a =>
         (Human_Id          => new String'("Warn_On_Anonymous_Allocators"),
          Status            => Active,
          Short_Name        => new String'("gnatw_a"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_c                      =>
-        (Human_Id => new String'("Warn_On_Unknown_Compile_Time_Warning"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_c =>
+        (Human_Id          =>
+           new String'("Warn_On_Unknown_Compile_Time_Warning"),
          Status            => Active,
          Short_Name        => new String'("gnatw_c"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_j                      =>
-        (Human_Id => new String'("Warn_On_Non_Dispatching_Primitives"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_j =>
+        (Human_Id          =>
+           new String'("Warn_On_Non_Dispatching_Primitives"),
          Status            => Active,
          Short_Name        => new String'("gnatw_j"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_l                      =>
-        (Human_Id => new String'("Warn_On_Inherently_Limited_Types"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_l =>
+        (Human_Id          => new String'("Warn_On_Inherently_Limited_Types"),
          Status            => Active,
          Short_Name        => new String'("gnatw_l"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_p                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_p =>
         (Human_Id          => new String'("Warn_On_Pedantic_Checks"),
          Status            => Active,
          Short_Name        => new String'("gnatw_p"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_q                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_q =>
         (Human_Id          => new String'("Warn_On_Ignored_Equality"),
          Status            => Active,
          Short_Name        => new String'("gnatw_q"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_r                      =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_r =>
         (Human_Id          => new String'("Warn_On_Component_Order"),
          Status            => Active,
          Short_Name        => new String'("gnatw_r"),
          Description       => null,
-         Documentation_Url => null),
-      gnatw_underscore_s                      =>
-        (Human_Id => new String'("Warn_On_Ineffective_Predicate_Test"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatw_underscore_s =>
+        (Human_Id          =>
+           new String'("Warn_On_Ineffective_Predicate_Test"),
          Status            => Active,
          Short_Name        => new String'("gnatw_s"),
          Description       => null,
-         Documentation_Url => null),
+         Documentation_Url => null,
+         Diagnostics       => null),
       --  NOTE: this flag is usually followed by a number specfifying the
       --  indentation level. We encode all of these warnings as -gnaty0
       --  irregardless of the actual numeric value.
-      gnaty      =>
+      gnaty              =>
         (Human_Id          => new String'("Style_Check_Indentation_Level"),
          Status            => Active,
          Short_Name        => new String'("gnaty0"),
          Description       => null,
-         Documentation_Url => null),
-      gnatya  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatya             =>
         (Human_Id          => new String'("Style_Check_Attribute_Casing"),
          Status            => Active,
          Short_Name        => new String'("gnatya"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyaa  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyaa            =>
         (Human_Id          => new String'("Address_Clause_Overlay_Warnings"),
          Status            => Active,
          Short_Name        => new String'("gnatyA"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyb  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyb             =>
         (Human_Id          => new String'("Style_Check_Blanks_At_End"),
          Status            => Active,
          Short_Name        => new String'("gnatyb"),
          Description       => null,
-         Documentation_Url => null),
-      gnatybb  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatybb            =>
         --  NOTE: in live documentation it is called "Check Boolean operators"
         (Human_Id          => new String'("Style_Check_Boolean_And_Or"),
          Status            => Active,
          Short_Name        => new String'("gnatyB"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyc  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyc             =>
         (Human_Id          => new String'("Style_Check_Comments_Double_Space"),
          Status            => Active,
          Short_Name        => new String'("gnatyc"),
          Description       => null,
-         Documentation_Url => null),
-      gnatycc  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatycc            =>
         (Human_Id          => new String'("Style_Check_Comments_Single_Space"),
          Status            => Active,
          Short_Name        => new String'("gnatyC"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyd  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyd             =>
         (Human_Id          => new String'("Style_Check_DOS_Line_Terminator"),
          Status            => Active,
          Short_Name        => new String'("gnatyd"),
          Description       => null,
-         Documentation_Url => null),
-      gnatydd  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatydd            =>
         (Human_Id          => new String'("Style_Check_Mixed_Case_Decls"),
          Status            => Active,
          Short_Name        => new String'("gnatyD"),
          Description       => null,
-         Documentation_Url => null),
-      gnatye  =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatye             =>
         (Human_Id          => new String'("Style_Check_End_Labels"),
          Status            => Active,
          Short_Name        => new String'("gnatye"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyf =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyf             =>
         (Human_Id          => new String'("Style_Check_Form_Feeds"),
          Status            => Active,
          Short_Name        => new String'("gnatyf"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyh =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyh             =>
         (Human_Id          => new String'("Style_Check_Horizontal_Tabs"),
          Status            => Active,
          Short_Name        => new String'("gnatyh"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyi =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyi             =>
         (Human_Id          => new String'("Style_Check_If_Then_Layout"),
          Status            => Active,
          Short_Name        => new String'("gnatyi"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyii =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyii            =>
         (Human_Id          => new String'("Style_Check_Mode_In"),
          Status            => Active,
          Short_Name        => new String'("gnatyI"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyk =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyk             =>
         (Human_Id          => new String'("Style_Check_Keyword_Casing"),
          Status            => Active,
          Short_Name        => new String'("gnatyk"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyl =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyl             =>
         (Human_Id          => new String'("Style_Check_Layout"),
          Status            => Active,
          Short_Name        => new String'("gnatyl"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyll =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyll            =>
         (Human_Id          => new String'("Style_Check_Max_Nesting_Level"),
          Status            => Active,
          Short_Name        => new String'("gnatyL"),
          Description       => null,
-         Documentation_Url => null),
-      gnatym =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatym             =>
         (Human_Id          => new String'("Style_Check_Max_Line_Length"),
          Status            => Active,
          Short_Name        => new String'("gnatym"),
          Description       => null,
-         Documentation_Url => null),
-      gnatymm =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatymm            =>
         --  TODO: May contain line length
         (Human_Id          => new String'("Style_Check_Max_Line_Length"),
          Status            => Active,
          Short_Name        => new String'("gnatyM"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyn =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyn             =>
         (Human_Id          => new String'("Style_Check_Standard"),
          Status            => Active,
          Short_Name        => new String'("gnatyn"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyo =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyo             =>
         (Human_Id          => new String'("Style_Check_Order_Subprograms"),
          Status            => Active,
          Short_Name        => new String'("gnatyo"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyoo =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyoo            =>
         (Human_Id          => new String'("Style_Check_Missing_Overriding"),
          Status            => Active,
          Short_Name        => new String'("gnatyO"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyp =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyp             =>
         (Human_Id          => new String'("Style_Check_Pragma_Casing"),
          Status            => Active,
          Short_Name        => new String'("gnatyp"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyr =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyr             =>
         (Human_Id          => new String'("Style_Check_References"),
          Status            => Active,
          Short_Name        => new String'("gnatyr"),
          Description       => null,
-         Documentation_Url => null),
-      gnatys =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatys             =>
         (Human_Id          => new String'("Style_Check_Specs"),
          Status            => Active,
          Short_Name        => new String'("gnatys"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyss =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyss            =>
         (Human_Id          => new String'("Style_Check_Separate_Stmt_Lines"),
          Status            => Active,
          Short_Name        => new String'("gnatyS"),
          Description       => null,
-         Documentation_Url => null),
-      gnatytt =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatytt            =>
         (Human_Id          => new String'("Style_Check_Tokens"),
          Status            => Active,
          Short_Name        => new String'("gnatyt"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyu =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyu             =>
         (Human_Id          => new String'("Style_Check_Blank_Lines"),
          Status            => Active,
          Short_Name        => new String'("gnatyu"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyx =>
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyx             =>
         (Human_Id          => new String'("Style_Check_Xtra_Parens"),
          Status            => Active,
          Short_Name        => new String'("gnatyx"),
          Description       => null,
-         Documentation_Url => null),
-      gnatyz =>
-        (Human_Id => new String'("Style_Check_Xtra_Parens_Precedence"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatyz             =>
+        (Human_Id          =>
+           new String'("Style_Check_Xtra_Parens_Precedence"),
          Status            => Active,
          Short_Name        => new String'("gnatyz"),
          Description       => null,
-         Documentation_Url => null),
-      gnatel =>
-        (Human_Id => new String'("Display_Elaboration_Messages"),
+         Documentation_Url => null,
+         Diagnostics       => null),
+      gnatel             =>
+        (Human_Id          => new String'("Display_Elaboration_Messages"),
          Status            => Active,
          Short_Name        => new String'("gnatel"),
          Description       => null,
-         Documentation_Url => null)
-      );
-
-   ----------------
-   -- Get_Switch --
-   ----------------
-
-   function Get_Switch (Id : Switch_Id) return Switch_Type is
-
-   begin
-      return Switches (Id);
-   end Get_Switch;
-
-   -------------------
-   -- Get_Switch_Id --
-   -------------------
-
-   function Get_Switch_Id (Name : String) return Switch_Id is
-      Trimmed_Name : constant String :=
-        (if Name (Name'Last) = ' ' then Name (Name'First .. Name'Last - 1)
-         else Name);
-   begin
-      for I in Active_Switch_Id loop
-         if Switches (I).Short_Name.all = Trimmed_Name then
-            return I;
-         end if;
-      end loop;
-
-      return No_Switch_Id;
-   end Get_Switch_Id;
-
-   -----------------------------
-   -- Print_Switch_Repository --
-   -----------------------------
-
-   procedure Print_Switch_Repository is
-      First : Boolean := True;
-   begin
-      Write_Char ('{');
-      Begin_Block;
-      NL_And_Indent;
-
-      Write_Str ("""" & "Switches" & """" & ": " & "[");
-      Begin_Block;
-
-      --  Avoid printing the first switch, which is a placeholder
-
-      for I in Active_Switch_Id loop
-
-         if First then
-            First := False;
-         else
-            Write_Char (',');
-         end if;
-
-         NL_And_Indent;
-
-         Write_Char ('{');
-         Begin_Block;
-         NL_And_Indent;
-
-         if Switches (I).Human_Id /= null then
-            Write_String_Attribute ("Human_Id", Switches (I).Human_Id.all);
-         else
-            Write_String_Attribute ("Human_Id", "null");
-         end if;
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Switches (I).Short_Name /= null then
-            Write_String_Attribute ("Short_Name", Switches (I).Short_Name.all);
-         else
-            Write_String_Attribute ("Short_Name", "null");
-         end if;
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Switches (I).Status = Active then
-            Write_String_Attribute ("Status", "Active");
-         else
-            Write_String_Attribute ("Status", "Deprecated");
-         end if;
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Switches (I).Description /= null then
-            Write_String_Attribute ("Description",
-                                     Switches (I).Description.all);
-         else
-            Write_String_Attribute ("Description", "null");
-         end if;
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Switches (I).Description /= null then
-            Write_String_Attribute ("Documentation_Url",
-                                    Switches (I).Description.all);
-         else
-            Write_String_Attribute ("Documentation_Url", "null");
-         end if;
-
-         End_Block;
-         NL_And_Indent;
-         Write_Char ('}');
-      end loop;
-
-      End_Block;
-      NL_And_Indent;
-      Write_Char (']');
-
-      End_Block;
-      NL_And_Indent;
-      Write_Char ('}');
+         Documentation_Url => null,
+         Diagnostics       => null));
 
-      Write_Eol;
-   end Print_Switch_Repository;
+   function Get_Switch_Id (Name : String) return Switch_Id;
+   --  Find the Switch_Id with a given Short_Name.
 
-end Errsw;
+end Errid.Switch_Repository;
diff --git a/gcc/ada/errid.adb b/gcc/ada/errid.adb
index 46d319e2d540..a432f016652b 100644
--- a/gcc/ada/errid.adb
+++ b/gcc/ada/errid.adb
@@ -23,11 +23,32 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with JSON_Utils; use JSON_Utils;
-with Output;     use Output;
+with Erroutc.SARIF_Emitter; use Erroutc.SARIF_Emitter;
 
 package body Errid is
 
+   Doc_Directory : constant String := "./error_codes";
+   Doc_Extension : constant String := ".md";
+
+   procedure Add_All_Diagnostic_Rules (Printer : in out SARIF_Printer);
+   --  Add all active Diagnostic_Id-s to the SARIF_Printer
+
+   procedure Add_All_Switch_Rules (Printer : in out SARIF_Printer);
+   --  Add all active Switch_Id-s to the SARIF_Printer
+
+   ----------------------------
+   -- Get_Documentation_File --
+   ----------------------------
+
+   function Get_Documentation_File (Id : Diagnostic_Id) return String is
+   begin
+      if Id = No_Diagnostic_Id then
+         return "";
+      else
+         return Doc_Directory & "/" & To_String (Id) & Doc_Extension;
+      end if;
+   end Get_Documentation_File;
+
    ---------------
    -- To_String --
    ---------------
@@ -41,94 +62,47 @@ package body Errid is
       end if;
    end To_String;
 
-   ---------------------------------
-   -- Print_Diagnostic_Repository --
-   ---------------------------------
+   ------------------------------
+   -- Add_All_Diagnostic_Rules --
+   ------------------------------
 
-   procedure Print_Diagnostic_Repository is
-      First : Boolean := True;
+   procedure Add_All_Diagnostic_Rules (Printer : in out SARIF_Printer) is
    begin
-      Write_Char ('{');
-      Begin_Block;
-      NL_And_Indent;
-
-      Write_Str ("""" & "Diagnostics" & """" & ": " & "[");
-      Begin_Block;
-
-      --  Avoid printing the first switch, which is a placeholder
-
-      for I in Diagnostic_Entries'First .. Diagnostic_Entries'Last loop
-
-         if First then
-            First := False;
-         else
-            Write_Char (',');
-         end if;
-
-         NL_And_Indent;
-
-         Write_Char ('{');
-         Begin_Block;
-         NL_And_Indent;
-
-         Write_String_Attribute ("Id", To_String (I));
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Diagnostic_Entries (I).Human_Id /= null then
-            Write_String_Attribute ("Human_Id",
-                                     Diagnostic_Entries (I).Human_Id.all);
-         else
-            Write_String_Attribute ("Human_Id", "null");
+      Printer.Diagnostics := Diagnostic_Id_Lists.Create;
+      for Id in Diagnostic_Id loop
+         if Id /= No_Diagnostic_Id then
+            Diagnostic_Id_Lists.Append (Printer.Diagnostics, Id);
          end if;
+      end loop;
+   end Add_All_Diagnostic_Rules;
 
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Diagnostic_Entries (I).Status = Active then
-            Write_String_Attribute ("Status", "Active");
-         else
-            Write_String_Attribute ("Status", "Deprecated");
-         end if;
-
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Diagnostic_Entries (I).Documentation /= null then
-            Write_String_Attribute ("Documentation",
-                                     Diagnostic_Entries (I).Documentation.all);
-         else
-            Write_String_Attribute ("Documentation", "null");
-         end if;
+   --------------------------
+   -- Add_All_Switch_Rules --
+   --------------------------
 
-         Write_Char (',');
-         NL_And_Indent;
-
-         if Diagnostic_Entries (I).Switch /= No_Switch_Id then
-            Write_Char (',');
-            NL_And_Indent;
-            Write_String_Attribute
-              ("Switch",
-               Get_Switch (Diagnostic_Entries (I).Switch).Human_Id.all);
-         else
-            Write_String_Attribute ("Switch", "null");
+   procedure Add_All_Switch_Rules (Printer : in out SARIF_Printer) is
+   begin
+      Printer.Switches := Switch_Id_Lists.Create;
+      for S in Switch_Id loop
+         if S /= No_Switch_Id then
+            Switch_Id_Lists.Append (Printer.Switches, S);
          end if;
-
-         End_Block;
-         NL_And_Indent;
-         Write_Char ('}');
       end loop;
+   end Add_All_Switch_Rules;
 
-      End_Block;
-      NL_And_Indent;
-      Write_Char (']');
+   ---------------------------------
+   -- Print_Diagnostic_Repository --
+   ---------------------------------
 
-      End_Block;
-      NL_And_Indent;
-      Write_Char ('}');
+   procedure Print_Diagnostic_Repository is
+      Printer : SARIF_Printer;
+   begin
+      Add_All_Diagnostic_Rules (Printer);
+      Add_All_Switch_Rules (Printer);
+      Printer.Report_Type := Repository_Report;
 
-      Write_Eol;
+      Print_SARIF_Report (Printer);
+      Free (Printer);
    end Print_Diagnostic_Repository;
 
 end Errid;
diff --git a/gcc/ada/errid.ads b/gcc/ada/errid.ads
index 4d56d73cdf57..312dd013a47f 100644
--- a/gcc/ada/errid.ads
+++ b/gcc/ada/errid.ads
@@ -23,9 +23,6 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Types; use Types;
-with Errsw; use Errsw;
-
 package Errid is
 
    type Status_Type is
@@ -41,77 +38,106 @@ package Errid is
       GNAT0005,
       GNAT0006);
 
-   function To_String (Id : Diagnostic_Id) return String;
-   --  Convert the diagnostic ID to a 4 character string padded with 0-s.
-
-   type Diagnostic_Entry_Type is record
-      Status : Status_Type := Active;
-
-      Human_Id : String_Ptr := null;
-      --  A human readable code for the diagnostic. If the diagnostic has a
-      --  switch with a human id then the human_id of the switch shall be used
-      --  in SARIF reports.
+   type Diagnostic_Id_Array is array (Positive range <>) of Diagnostic_Id;
+   type Diagnostic_Id_Array_Access is access Diagnostic_Id_Array;
+   type Switch_Id is (
+      No_Switch_Id,
+      gnatel,
+      gnatwb,
+      gnatwc,
+      gnatwd,
+      gnatwf,
+      gnatwg,
+      gnatwh,
+      gnatwi,
+      gnatwj,
+      gnatwk,
+      gnatwl,
+      gnatwm,
+      gnatwo,
+      gnatwp,
+      gnatwq,
+      gnatwr,
+      gnatwt,
+      gnatwu,
+      gnatwv,
+      gnatww,
+      gnatwx,
+      gnatwy,
+      gnatwz,
+      gnatw_dot_a,
+      gnatw_dot_b,
+      gnatw_dot_c,
+      gnatw_dot_f,
+      gnatw_dot_h,
+      gnatw_dot_i,
+      gnatw_dot_j,
+      gnatw_dot_k,
+      gnatw_dot_l,
+      gnatw_dot_m,
+      gnatw_dot_n,
+      gnatw_dot_o,
+      gnatw_dot_p,
+      gnatw_dot_q,
+      gnatw_dot_r,
+      gnatw_dot_s,
+      gnatw_dot_t,
+      gnatw_dot_u,
+      gnatw_dot_v,
+      gnatw_dot_w,
+      gnatw_dot_x,
+      gnatw_dot_y,
+      gnatw_dot_z,
+      gnatw_underscore_a,
+      gnatw_underscore_c,
+      gnatw_underscore_j,
+      gnatw_underscore_l,
+      gnatw_underscore_p,
+      gnatw_underscore_q,
+      gnatw_underscore_r,
+      gnatw_underscore_s,
+      gnaty,
+      gnatya,
+      gnatyb,
+      gnatyc,
+      gnatyd,
+      gnatye,
+      gnatyf,
+      gnatyh,
+      gnatyi,
+      gnatyk,
+      gnatyl,
+      gnatym,
+      gnatyn,
+      gnatyo,
+      gnatyp,
+      gnatyr,
+      gnatys,
+      gnatyu,
+      gnatyx,
+      gnatyz,
+      gnatyaa,
+      gnatybb,
+      gnatycc,
+      gnatydd,
+      gnatyii,
+      gnatyll,
+      gnatymm,
+      gnatyoo,
+      gnatyss,
+      gnatytt
+   );
 
-      Documentation : String_Ptr := null;
+   subtype Active_Switch_Id is Switch_Id range gnatel .. gnatytt;
 
-      Switch : Switch_Id := No_Switch_Id;
-      --  The switch that controls the diagnostic message.
-   end record;
+   function Get_Documentation_File (Id : Diagnostic_Id) return String;
+   --  Return the location of the documentation file as a string.
 
-   type Diagnostics_Registry_Type is
-     array (Diagnostic_Id) of Diagnostic_Entry_Type;
-
-   --  Include the diagnostic entries for every diagnostic id.
-   --  The entries should include:
-   --  * Whether the diagnostic with this id is active or not
-   --  * The human-readable name for the diagnostic for SARIF reports
-   --  * The switch id for the diagnostic if the diagnostic is linked to any
-   --    compiler switch
-   --  * The documentation file for the diagnostic written in the MD format.
-   --    The documentation file should include:
-   --    - The diagnostic id
-   --    - A short description of the diagnostic
-   --    - A minimal example of the code that triggers the diagnostic
-   --    - An explanation of why the diagnostic was triggered
-   --    - A suggestion on how to fix the issue
-   --    - Optionally additional information
-   --    TODO: the mandatory fields for the documentation file could be changed
-
-   Diagnostic_Entries : constant Diagnostics_Registry_Type :=
-     (No_Diagnostic_Id => <>,
-      GNAT0001         =>
-        (Status        => Active,
-         Human_Id      => new String'("Default_Iterator_Not_Primitive_Error"),
-         Documentation => new String'("./error_codes/GNAT0001.md"),
-         Switch        => No_Switch_Id),
-      GNAT0002         =>
-        (Status        => Active,
-         Human_Id      =>
-           new String'("Invalid_Operand_Types_General_Error"),
-         Documentation => new String'("./error_codes/GNAT0007.md"),
-         Switch        => No_Switch_Id),
-      GNAT0003         =>
-        (Status        => Active,
-         Human_Id      =>
-           new String'("Pragma_No_Effect_With_Lock_Free_Warning"),
-         Documentation => new String'("./error_codes/GNAT0008.md"),
-         Switch        => No_Switch_Id),
-      GNAT0004         =>
-        (Status        => Active,
-         Human_Id      => new String'("End_Loop_Expected_Error"),
-         Documentation => new String'("./error_codes/GNAT0009.md"),
-         Switch        => No_Switch_Id),
-      GNAT0005         =>
-        (Status        => Active,
-         Human_Id      => new String'("Representation_Too_Late_Error"),
-         Documentation => new String'("./error_codes/GNAT0010.md"),
-         Switch        => No_Switch_Id),
-      GNAT0006         =>
-        (Status        => Active,
-         Human_Id      => new String'("Mixed_Container_Aggregate_Error"),
-         Documentation => new String'("./error_codes/GNAT0011.md"),
-         Switch        => No_Switch_Id));
+   function To_String (Id : Diagnostic_Id) return String;
+   --  Convert the diagnostic ID to a 4 character string padded with 0-s.
 
    procedure Print_Diagnostic_Repository;
+   --  Print all of the Diagnostic_Id-s and Switch_Id-s as rules in the SARIF
+   --  format.
 
 end Errid;
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index e6d0dbcd2ab0..a5c68dd87183 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -37,8 +37,7 @@ with Einfo.Entities; use Einfo.Entities;
 with Einfo.Utils;    use Einfo.Utils;
 with Erroutc;        use Erroutc;
 with Erroutc.Pretty_Emitter;
-with Erroutc.SARIF_Emitter;
-with Errsw;          use Errsw;
+with Erroutc.SARIF_Emitter; use Erroutc.SARIF_Emitter;
 with Gnatvsn;        use Gnatvsn;
 with Lib;            use Lib;
 with Opt;            use Opt;
@@ -96,6 +95,10 @@ package body Errout is
    -- Local Subprograms --
    -----------------------
 
+   procedure Add_Unique_Diagnostics_And_Switches
+     (Printer : in out SARIF_Printer);
+   --  Fill the printer with the unique diagnostic and switch id.
+
    procedure Error_Msg_Internal
      (Msg        : String;
       Span       : Source_Span;
@@ -216,6 +219,92 @@ package body Errout is
    --    " "     returns "?"
    --    other   trimmed, prefixed and suffixed with "?".
 
+   -----------------------------------------
+   -- Add_Unique_Diagnostics_And_Switches --
+   -----------------------------------------
+
+   procedure Add_Unique_Diagnostics_And_Switches
+     (Printer : in out SARIF_Printer)
+   is
+      E_Id  : Error_Msg_Id;
+      E_Obj : Error_Msg_Object;
+
+      procedure Insert_Diagnostic (D : Diagnostic_Id);
+      --  Insert a diagnostic to the printers diagnostic list by adding them in
+      --  the same order as they are defined (alphanumerically).
+
+      procedure Insert_Switch (S : Switch_Id);
+      --  Insert a switch to the printers swtiches list by adding them in
+      --  the same order as they are defined (alphanumerically).
+
+      -----------------------
+      -- Insert_Diagnostic --
+      -----------------------
+
+      procedure Insert_Diagnostic (D : Diagnostic_Id) is
+         use Diagnostic_Id_Lists;
+         It : Iterator := Iterate (Printer.Diagnostics);
+         El : Diagnostic_Id;
+      begin
+         while Has_Next (It) loop
+            Next (It, El);
+
+            if El = D then
+               return;
+            elsif El > D then
+               Insert_Before (Printer.Diagnostics, El, D);
+               return;
+            end if;
+         end loop;
+
+         Append (Printer.Diagnostics, D);
+      end Insert_Diagnostic;
+
+      -------------------
+      -- Insert_Switch --
+      -------------------
+
+      procedure Insert_Switch (S : Switch_Id) is
+         use Switch_Id_Lists;
+         It : Iterator := Iterate (Printer.Switches);
+         El : Switch_Id;
+      begin
+         --  Do not add a switch if the diagnostic was not using one
+
+         if S = No_Switch_Id then
+            return;
+         end if;
+
+         while Has_Next (It) loop
+            Next (It, El);
+
+            if El = S then
+               return;
+            elsif El > S then
+               Insert_Before (Printer.Switches, El, S);
+               return;
+            end if;
+         end loop;
+
+         Switch_Id_Lists.Append (Printer.Switches, S);
+      end Insert_Switch;
+
+      --  Start of processing for Add_Unique_Diagnostics_And_Switches
+
+   begin
+      Printer.Diagnostics := Diagnostic_Id_Lists.Create;
+      Printer.Switches := Switch_Id_Lists.Create;
+
+      E_Id := First_Error_Msg;
+      while E_Id /= No_Error_Msg loop
+         E_Obj := Errors.Table (E_Id);
+         Insert_Diagnostic (E_Obj.Id);
+         Insert_Switch (E_Obj.Switch);
+
+         Next_Error_Msg (E_Id);
+      end loop;
+   end Add_Unique_Diagnostics_And_Switches;
+
    -----------------------
    -- Change_Error_Text --
    -----------------------
@@ -2800,8 +2889,9 @@ package body Errout is
 
       Sarif_File_Name       : constant String :=
         Get_First_Main_File_Name & ".gnat.sarif";
-      Switches_File_Name    : constant String := "gnat_switches.json";
-      Diagnostics_File_Name : constant String := "gnat_diagnostics.json";
+      Diagnostics_File_Name : constant String := "gnat_diagnostics.sarif";
+
+      Printer : Erroutc.SARIF_Emitter.SARIF_Printer;
 
       Dummy : Boolean;
 
@@ -2880,7 +2970,9 @@ package body Errout is
 
          if Opt.SARIF_Output then
             Set_Standard_Error;
-            Erroutc.SARIF_Emitter.Print_SARIF_Report;
+            Add_Unique_Diagnostics_And_Switches (Printer);
+            Print_SARIF_Report (Printer);
+            Free (Printer);
             Set_Standard_Output;
 
          elsif Opt.SARIF_File then
@@ -2890,10 +2982,11 @@ package body Errout is
                  constant System.OS_Lib.File_Descriptor :=
                  System.OS_Lib.Create_New_File
                    (Sarif_File_Name, Fmode => System.OS_Lib.Text);
-
             begin
                Set_Output (Output_FD);
-               Erroutc.SARIF_Emitter.Print_SARIF_Report;
+               Add_Unique_Diagnostics_And_Switches (Printer);
+               Print_SARIF_Report (Printer);
+               Free (Printer);
                Set_Standard_Output;
                System.OS_Lib.Close (Output_FD);
             end;
@@ -2905,24 +2998,6 @@ package body Errout is
       end if;
 
       if Debug_Flag_Underscore_EE then
-         --  Print the switch repository to a file
-
-         System.OS_Lib.Delete_File (Switches_File_Name, Dummy);
-         declare
-            Output_FD : constant System.OS_Lib.File_Descriptor :=
-              System.OS_Lib.Create_New_File
-                (Switches_File_Name,
-                 Fmode => System.OS_Lib.Text);
-
-         begin
-            Set_Output (Output_FD);
-
-            Print_Switch_Repository;
-
-            Set_Standard_Output;
-
-            System.OS_Lib.Close (Output_FD);
-         end;
 
          --  Print the diagnostics repository to a file
 
diff --git a/gcc/ada/erroutc-sarif_emitter.adb 
b/gcc/ada/erroutc-sarif_emitter.adb
index 1d4df0c6f691..9c22c9bdf7d2 100644
--- a/gcc/ada/erroutc-sarif_emitter.adb
+++ b/gcc/ada/erroutc-sarif_emitter.adb
@@ -23,13 +23,14 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with JSON_Utils; use JSON_Utils;
-with GNAT.Lists; use GNAT.Lists;
-with Gnatvsn;    use Gnatvsn;
-with Lib;        use Lib;
-with Namet;      use Namet;
-with Output;     use Output;
-with Sinput;     use Sinput;
+with Errid.Diagnostic_Repository; use Errid.Diagnostic_Repository;
+with Errid.Switch_Repository;     use Errid.Switch_Repository;
+with JSON_Utils;                  use JSON_Utils;
+with Gnatvsn;                     use Gnatvsn;
+with Lib;                         use Lib;
+with Namet;                       use Namet;
+with Output;                      use Output;
+with Sinput;                      use Sinput;
 with System.OS_Lib;
 
 package body Erroutc.SARIF_Emitter is
@@ -49,6 +50,7 @@ package body Erroutc.SARIF_Emitter is
    N_ID                    : constant String := "id";
    N_INSERTED_CONTENT      : constant String := "insertedContent";
    N_INVOCATIONS           : constant String := "invocations";
+   N_KINDS                 : constant String := "kinds";
    N_LOCATIONS             : constant String := "locations";
    N_LEVEL                 : constant String := "level";
    N_MESSAGE               : constant String := "message";
@@ -57,6 +59,7 @@ package body Erroutc.SARIF_Emitter is
    N_PHYSICAL_LOCATION     : constant String := "physicalLocation";
    N_REGION                : constant String := "region";
    N_RELATED_LOCATIONS     : constant String := "relatedLocations";
+   N_RELATIONSHIPS         : constant String := "relationships";
    N_REPLACEMENTS          : constant String := "replacements";
    N_RESULTS               : constant String := "results";
    N_RULES                 : constant String := "rules";
@@ -65,6 +68,7 @@ package body Erroutc.SARIF_Emitter is
    N_SCHEMA                : constant String := "$schema";
    N_START_COLUMN          : constant String := "startColumn";
    N_START_LINE            : constant String := "startLine";
+   N_TARGET                : constant String := "target";
    N_TEXT                  : constant String := "text";
    N_TOOL                  : constant String := "tool";
    N_URI                   : constant String := "uri";
@@ -75,7 +79,7 @@ package body Erroutc.SARIF_Emitter is
 
    SARIF_Version : constant String := "2.1.0";
    pragma Style_Checks ("M100");
-   SARIF_Schema : constant String :=
+   SARIF_Schema  : constant String :=
      
"https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json";;
    pragma Style_Checks ("M79");
 
@@ -88,16 +92,6 @@ package body Erroutc.SARIF_Emitter is
    --  and it is also the path that all other Uri attributes will be created
    --  relative to.
 
-   procedure Destroy (Elem : in out Error_Msg_Object) is null;
-   pragma Inline (Destroy);
-   package Error_Msg_Lists is new Doubly_Linked_Lists
-     (Element_Type    => Error_Msg_Object,
-      "="             => "=",
-      Destroy_Element => Destroy,
-      Check_Tampering => False);
-
-   subtype Error_Msg_List is Error_Msg_Lists.Doubly_Linked_List;
-
    procedure Destroy (Elem : in out Edit_Type);
 
    procedure Destroy (Elem : in out Edit_Type) is
@@ -143,9 +137,6 @@ package body Erroutc.SARIF_Emitter is
    --  Group edits of a Fix into Artifact_Changes that organize the edits by
    --  file name.
 
-   function Get_Unique_Rules return Error_Msg_List;
-   --  Get a list of diagnostics that have unique Diagnostic Id-s.
-
    procedure Print_Replacement (Replacement : Edit_Type);
    --  Print a replacement node
    --
@@ -292,6 +283,16 @@ package body Erroutc.SARIF_Emitter is
    --  the GNAT span definition and we amend the endColumn value so that it
    --  matches the SARIF definition.
 
+   procedure Print_Relationship (Target : String; Kind : String);
+   --  {
+   --     "target": {
+   --        "id": <Target>
+   --     },
+   --     "kinds": [
+   --        <kind>
+   --     ]
+   --  }
+
    procedure Print_Result (E_Msg : Error_Msg_Object);
    --   {
    --     "ruleId": <Diag.Id>,
@@ -311,7 +312,7 @@ package body Erroutc.SARIF_Emitter is
    --     <Result (Diag)>
    --   ]
 
-   procedure Print_Rule (E : Error_Msg_Object);
+   procedure Print_Rule (E : Diagnostic_Id);
    --  Print a rule node that consists of the following attributes:
    --  * ruleId
    --  * name
@@ -321,7 +322,17 @@ package body Erroutc.SARIF_Emitter is
    --    "name": <Human_Id(Diag)>
    --  },
 
-   procedure Print_Rules;
+   procedure Print_Rule (S : Switch_Id);
+   --  Print a rule node that consists of the following attributes:
+   --  * ruleId
+   --  * name
+   --
+   --  {
+   --    "id": <Switch.Id>,
+   --    "name": <Human_Id(S)>
+   --  },
+
+   procedure Print_Rules (Self : SARIF_Printer);
    --  Print a rules node that consists of multiple rule nodes.
    --  Rules are considered to be a set of unique diagnostics with the unique
    --  id-s.
@@ -330,7 +341,7 @@ package body Erroutc.SARIF_Emitter is
    --     <Rule (Diag)>
    --   ]
 
-   procedure Print_Runs;
+   procedure Print_Runs (Self : SARIF_Printer);
    --  Print a runs node that can consist of multiple run nodes.
    --  However for our report it consists of a single run that consists of
    --  * a tool node
@@ -341,7 +352,7 @@ package body Erroutc.SARIF_Emitter is
    --     "results": [<Results (Diags)>]
    --   }
 
-   procedure Print_Tool;
+   procedure Print_Tool (Self : SARIF_Printer);
    --  Print a tool node that consists of
    --  * a driver node that consists of:
    --    * name
@@ -365,6 +376,21 @@ package body Erroutc.SARIF_Emitter is
       Edit_Lists.Destroy (Elem.Replacements);
    end Destroy;
 
+   ----------
+   -- Free --
+   ----------
+
+   procedure Free (Self : in out SARIF_Printer) is
+   begin
+      if Diagnostic_Id_Lists.Present (Self.Diagnostics) then
+         Diagnostic_Id_Lists.Destroy (Self.Diagnostics);
+      end if;
+
+      if Switch_Id_Lists.Present (Self.Switches) then
+         Switch_Id_Lists.Destroy (Self.Switches);
+      end if;
+   end Free;
+
    --------------------------
    -- Get_Artifact_Changes --
    --------------------------
@@ -425,54 +451,6 @@ package body Erroutc.SARIF_Emitter is
       return Changes;
    end Get_Artifact_Changes;
 
-   ----------------------
-   -- Get_Unique_Rules --
-   ----------------------
-
-   function Get_Unique_Rules return Error_Msg_List is
-      use Error_Msg_Lists;
-
-      procedure Insert (Rules : Error_Msg_List; E : Error_Msg_Object);
-
-      ------------
-      -- Insert --
-      ------------
-
-      procedure Insert (Rules : Error_Msg_List; E : Error_Msg_Object) is
-         It : Iterator := Iterate (Rules);
-         R  : Error_Msg_Object;
-      begin
-         while Has_Next (It) loop
-            Next (It, R);
-
-            if R.Id = E.Id then
-               return;
-            elsif R.Id > E.Id then
-               Insert_Before (Rules, R, E);
-               return;
-            end if;
-         end loop;
-
-         Append (Rules, E);
-      end Insert;
-
-      Unique_Rules : constant Error_Msg_List := Create;
-
-      E : Error_Msg_Id;
-
-      --  Start of processing for Get_Unique_Rules
-
-   begin
-      E := First_Error_Msg;
-      while E /= No_Error_Msg loop
-         Insert (Unique_Rules, Errors.Table (E));
-
-         Next_Error_Msg (E);
-      end loop;
-
-      return Unique_Rules;
-   end Get_Unique_Rules;
-
    ---------------------------
    -- Print_Artifact_Change --
    ---------------------------
@@ -777,9 +755,8 @@ package body Erroutc.SARIF_Emitter is
      (Start_Line : Int;
       Start_Col  : Int;
       End_Line   : Int;
-       End_Col   : Int;
-      Name       : String := N_REGION)
-   is
+      End_Col    : Int;
+      Name       : String := N_REGION) is
 
    begin
       Write_Str ("""" & Name & """" & ": " & "{");
@@ -1033,6 +1010,47 @@ package body Erroutc.SARIF_Emitter is
       Write_Char (']');
    end Print_Related_Locations;
 
+   ------------------------
+   -- Print_Relationship --
+   ------------------------
+
+   procedure Print_Relationship (Target : String; Kind : String) is
+   begin
+      Write_Char ('{');
+      Begin_Block;
+      NL_And_Indent;
+
+      Write_Str ("""" & N_TARGET & """" & ": " & "{");
+      Begin_Block;
+
+      NL_And_Indent;
+      Write_String_Attribute (N_ID, Target);
+
+      End_Block;
+      NL_And_Indent;
+      Write_Char ('}');
+
+      Write_Char (',');
+      NL_And_Indent;
+
+      Write_Str ("""" & N_KINDS & """" & ": " & "[");
+      Begin_Block;
+
+      NL_And_Indent;
+      Write_Char ('"');
+      Write_JSON_Escaped_String (Kind);
+      Write_Char ('"');
+
+      End_Block;
+      NL_And_Indent;
+      Write_Char (']');
+
+      End_Block;
+      NL_And_Indent;
+
+      Write_Char ('}');
+   end Print_Relationship;
+
    ------------------
    -- Print_Result --
    ------------------
@@ -1046,7 +1064,7 @@ package body Erroutc.SARIF_Emitter is
 
       --  Print ruleId
 
-      Write_String_Attribute (N_RULE_ID, "[" & To_String (E_Msg.Id) & "]");
+      Write_String_Attribute (N_RULE_ID, To_String (E_Msg.Id));
 
       Write_Char (',');
       NL_And_Indent;
@@ -1125,14 +1143,15 @@ package body Erroutc.SARIF_Emitter is
    -- Print_Rule --
    ----------------
 
-   procedure Print_Rule (E : Error_Msg_Object) is
-      Human_Id : constant String_Ptr := Get_Human_Id (E);
+   procedure Print_Rule (E : Diagnostic_Id) is
+      Human_Id : constant String_Ptr := Diagnostic_Entries (E).Human_Id;
+      Switch   : constant Switch_Id := Diagnostic_Entries (E).Switch;
    begin
       Write_Char ('{');
       Begin_Block;
       NL_And_Indent;
 
-      Write_String_Attribute (N_ID, "[" & To_String (E.Id) & "]");
+      Write_String_Attribute (N_ID, To_String (E));
       Write_Char (',');
       NL_And_Indent;
 
@@ -1142,6 +1161,63 @@ package body Erroutc.SARIF_Emitter is
          Write_String_Attribute (N_NAME, Human_Id.all);
       end if;
 
+      if Switch /= No_Switch_Id then
+         Write_Char (',');
+         NL_And_Indent;
+
+         Write_Str ("""" & N_RELATIONSHIPS & """" & ": " & "[");
+         Begin_Block;
+
+         NL_And_Indent;
+         Print_Relationship (Switches (Switch).Short_Name.all, "superset");
+
+         End_Block;
+         NL_And_Indent;
+         Write_Char (']');
+      end if;
+
+      End_Block;
+      NL_And_Indent;
+      Write_Char ('}');
+   end Print_Rule;
+
+   procedure Print_Rule (S : Switch_Id) is
+      First : Boolean := True;
+   begin
+      pragma Assert (S /= No_Switch_Id);
+
+      Write_Char ('{');
+      Begin_Block;
+      NL_And_Indent;
+
+      Write_String_Attribute (N_ID, Switches (S).Short_Name.all);
+      Write_Char (',');
+      NL_And_Indent;
+
+      Write_String_Attribute (N_NAME, Switches (S).Human_Id.all);
+
+      if Switches (S).Diagnostics /= null then
+         Write_Char (',');
+         NL_And_Indent;
+
+         Write_Str ("""" & N_RELATIONSHIPS & """" & ": " & "[");
+         Begin_Block;
+         NL_And_Indent;
+
+         for D of Switches (S).Diagnostics.all loop
+            if First then
+               First := False;
+            else
+               Write_Char (',');
+            end if;
+            Print_Relationship (To_String (D), "subset");
+         end loop;
+
+         End_Block;
+         NL_And_Indent;
+         Write_Char (']');
+      end if;
+
       End_Block;
       NL_And_Indent;
       Write_Char ('}');
@@ -1151,19 +1227,21 @@ package body Erroutc.SARIF_Emitter is
    -- Print_Rules --
    -----------------
 
-   procedure Print_Rules is
-      use Error_Msg_Lists;
-      R     : Error_Msg_Object;
-      Rules : Error_Msg_List := Get_Unique_Rules;
-      It    : Iterator       := Iterate (Rules);
+   procedure Print_Rules (Self : SARIF_Printer) is
+      D       : Diagnostic_Id;
+      S       : Switch_Id;
+      Diag_It : Diagnostic_Id_Lists.Iterator :=
+        Diagnostic_Id_Lists.Iterate (Self.Diagnostics);
+      Sw_It   : Switch_Id_Lists.Iterator :=
+        Switch_Id_Lists.Iterate (Self.Switches);
 
       First : Boolean := True;
    begin
       Write_Str ("""" & N_RULES & """" & ": " & "[");
       Begin_Block;
 
-      while Has_Next (It) loop
-         Next (It, R);
+      while Diagnostic_Id_Lists.Has_Next (Diag_It) loop
+         Diagnostic_Id_Lists.Next (Diag_It, D);
 
          if First then
             First := False;
@@ -1172,21 +1250,28 @@ package body Erroutc.SARIF_Emitter is
          end if;
 
          NL_And_Indent;
-         Print_Rule (R);
+         Print_Rule (D);
+      end loop;
+
+      while Switch_Id_Lists.Has_Next (Sw_It) loop
+         Switch_Id_Lists.Next (Sw_It, S);
+
+         Write_Char (',');
+
+         NL_And_Indent;
+         Print_Rule (S);
       end loop;
 
       End_Block;
       NL_And_Indent;
       Write_Char (']');
-
-      Error_Msg_Lists.Destroy (Rules);
    end Print_Rules;
 
    ----------------
    -- Print_Tool --
    ----------------
 
-   procedure Print_Tool is
+   procedure Print_Tool (Self : SARIF_Printer) is
 
    begin
       Write_Str ("""" & N_TOOL & """" & ": " & "{");
@@ -1209,7 +1294,7 @@ package body Erroutc.SARIF_Emitter is
       Write_Char (',');
       NL_And_Indent;
 
-      Print_Rules;
+      Print_Rules (Self);
 
       --  End of tool.driver
 
@@ -1230,7 +1315,7 @@ package body Erroutc.SARIF_Emitter is
    -- Print_Runs --
    ----------------
 
-   procedure Print_Runs is
+   procedure Print_Runs (Self : SARIF_Printer) is
 
    begin
       Write_Str ("""" & N_RUNS & """" & ": " & "[");
@@ -1246,24 +1331,30 @@ package body Erroutc.SARIF_Emitter is
 
       --  A run consists of a tool
 
-      Print_Tool;
+      Print_Tool (Self);
 
-      Write_Char (',');
-      NL_And_Indent;
+      --  Print the Invocation and Results only in the Diagnostic_Report but
+      --  not during the Repository_Report.
 
-      --  A run consists of an invocation
-      Print_Invocations;
+      if Self.Report_Type = Diagnostic_Report then
 
-      Write_Char (',');
-      NL_And_Indent;
+         Write_Char (',');
+         NL_And_Indent;
 
-      Print_Original_Uri_Base_Ids;
-      Write_Char (',');
-      NL_And_Indent;
+         --  A run consists of an invocation
+         Print_Invocations;
 
-      --  A run consists of results
+         Write_Char (',');
+         NL_And_Indent;
 
-      Print_Results;
+         Print_Original_Uri_Base_Ids;
+         Write_Char (',');
+         NL_And_Indent;
+
+         --  A run consists of results
+
+         Print_Results;
+      end if;
 
       --  End of run
 
@@ -1284,7 +1375,7 @@ package body Erroutc.SARIF_Emitter is
    -- Print_SARIF_Report --
    ------------------------
 
-   procedure Print_SARIF_Report is
+   procedure Print_SARIF_Report (Self : SARIF_Printer) is
    begin
       Write_Char ('{');
       Begin_Block;
@@ -1298,7 +1389,7 @@ package body Erroutc.SARIF_Emitter is
       Write_Char (',');
       NL_And_Indent;
 
-      Print_Runs;
+      Print_Runs (Self);
 
       End_Block;
       NL_And_Indent;
diff --git a/gcc/ada/erroutc-sarif_emitter.ads 
b/gcc/ada/erroutc-sarif_emitter.ads
index e3953712f85b..2813e829b4ec 100644
--- a/gcc/ada/erroutc-sarif_emitter.ads
+++ b/gcc/ada/erroutc-sarif_emitter.ads
@@ -22,7 +22,55 @@
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
-
+with GNAT.Lists; use GNAT.Lists;
 package Erroutc.SARIF_Emitter is
-   procedure Print_SARIF_Report;
+
+   procedure Destroy (Elem : in out Switch_Id) is null;
+   pragma Inline (Destroy);
+   package Switch_Id_Lists is new Doubly_Linked_Lists
+     (Element_Type    => Switch_Id,
+      "="             => "=",
+      Destroy_Element => Destroy,
+      Check_Tampering => False);
+   subtype Switch_Id_List is Switch_Id_Lists.Doubly_Linked_List;
+
+   procedure Destroy (Elem : in out Diagnostic_Id) is null;
+   pragma Inline (Destroy);
+   package Diagnostic_Id_Lists is new Doubly_Linked_Lists
+     (Element_Type    => Diagnostic_Id,
+      "="             => "=",
+      Destroy_Element => Destroy,
+      Check_Tampering => False);
+
+   subtype Diagnostic_Id_List is Diagnostic_Id_Lists.Doubly_Linked_List;
+
+   type Report_Kind is (Diagnostic_Report, Repository_Report);
+   --  SARIF emitter is used to produce two different types of reports:
+   --
+   --  Diagnostic_Report - This report includes all of the diagnostics gathered
+   --  by the tool under the results, the commandline used to start the tool
+   --  under the invocations and all of the unique rules in the emitted
+   --  diagnostics under the rules section.
+   --
+   --  Repository_Report - This report inludes all of the defined
+   --  Diagnostic_Id-s and Switch_Id-s as rules but does not contain an
+   --  invocation or a result section.
+
+   type SARIF_Printer is record
+      Diagnostics : Diagnostic_Id_List;
+      --  Unique diagnostics printed as rules in the SARIF report
+
+      Switches : Switch_Id_List;
+      --  Unique switches printed as rules in the SARIF report
+
+      Report_Type : Report_Kind := Diagnostic_Report;
+      --  The type of report to be printed in SARIF
+   end record;
+
+   procedure Free (Self : in out SARIF_Printer);
+   --  Free memory for the SARIF_Pritner
+
+   procedure Print_SARIF_Report (Self : SARIF_Printer);
+   --  Prints the SARIF report to the currently selected output.
+
 end Erroutc.SARIF_Emitter;
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index bbc41c733dc2..92e0e5a0efba 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -34,6 +34,7 @@ with Casing;   use Casing;
 with Csets;    use Csets;
 with Debug;    use Debug;
 with Err_Vars; use Err_Vars;
+with Errid.Switch_Repository; use Errid.Switch_Repository;
 with Fname;    use Fname;
 with Namet;    use Namet;
 with Opt;      use Opt;
@@ -532,19 +533,6 @@ package body Erroutc is
       return No_Labeled_Span;
    end Primary_Location;
 
-   ------------------
-   -- Get_Human_Id --
-   ------------------
-
-   function Get_Human_Id (E : Error_Msg_Object) return String_Ptr is
-   begin
-      if E.Switch = No_Switch_Id then
-         return Diagnostic_Entries (E.Id).Human_Id;
-      else
-         return Get_Switch (E).Human_Id;
-      end if;
-   end Get_Human_Id;
-
    --------------------
    -- Get_Doc_Switch --
    --------------------
@@ -571,26 +559,13 @@ package body Erroutc is
                return "[enabled by default]";
             end if;
          else
-            declare
-               S : constant Switch_Type := Get_Switch (E);
-            begin
-               return "[-" & S.Short_Name.all & "]";
-            end;
+            return "[-" & Switches (E.Switch).Short_Name.all & "]";
          end if;
       end if;
 
       return "";
    end Get_Doc_Switch;
 
-   ----------------
-   -- Get_Switch --
-   ----------------
-
-   function Get_Switch (E : Error_Msg_Object) return Switch_Type is
-   begin
-      return Get_Switch (E.Switch);
-   end Get_Switch;
-
    -------------------
    -- Get_Switch_Id --
    -------------------
diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads
index 2d8499a5bffd..f35de2420070 100644
--- a/gcc/ada/erroutc.ads
+++ b/gcc/ada/erroutc.ads
@@ -27,7 +27,6 @@
 --  reporting packages, including Errout and Prj.Err.
 
 with Table;
-with Errsw; use Errsw;
 with Errid; use Errid;
 with Osint; use Osint;
 with Types; use Types;
@@ -420,13 +419,6 @@ package Erroutc is
    --  Returns the first Primary Labeled_Span associated with the error
    --  message. Otherwise it returns No_Labeled_Span.
 
-   function Get_Human_Id (E : Error_Msg_Object) return String_Ptr;
-   --  Returns a longer human readable name for the switch associated with the
-   --  error message.
-
-   function Get_Switch (E : Error_Msg_Object) return Switch_Type;
-   --  Returns the Switch information for the given error message
-
    function Get_Switch_Id (E : Error_Msg_Object) return Switch_Id;
    --  Returns the Switch information identifier for the given error message
 
diff --git a/gcc/ada/errsw.ads b/gcc/ada/errsw.ads
deleted file mode 100644
index 93af18296bb3..000000000000
--- a/gcc/ada/errsw.ads
+++ /dev/null
@@ -1,155 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT COMPILER COMPONENTS                         --
---                                                                          --
---                                E R R S W                                 --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---          Copyright (C) 1992-2025, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
--- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
--- http://www.gnu.org/licenses for a complete copy of the license.          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-with Types; use Types;
-
-package Errsw is
-
-   type Status_Type is
-     (Active,
-      Deprecated);
-
-   type Switch_Id is (
-      No_Switch_Id,
-      gnatwb,
-      gnatwc,
-      gnatwd,
-      gnatwf,
-      gnatwg,
-      gnatwh,
-      gnatwi,
-      gnatwj,
-      gnatwk,
-      gnatwl,
-      gnatwm,
-      gnatwo,
-      gnatwp,
-      gnatwq,
-      gnatwr,
-      gnatwt,
-      gnatwu,
-      gnatwv,
-      gnatww,
-      gnatwx,
-      gnatwy,
-      gnatwz,
-      gnatw_dot_a,
-      gnatw_dot_b,
-      gnatw_dot_c,
-      gnatw_dot_f,
-      gnatw_dot_h,
-      gnatw_dot_i,
-      gnatw_dot_j,
-      gnatw_dot_k,
-      gnatw_dot_l,
-      gnatw_dot_m,
-      gnatw_dot_n,
-      gnatw_dot_o,
-      gnatw_dot_p,
-      gnatw_dot_q,
-      gnatw_dot_r,
-      gnatw_dot_s,
-      gnatw_dot_t,
-      gnatw_dot_u,
-      gnatw_dot_v,
-      gnatw_dot_w,
-      gnatw_dot_x,
-      gnatw_dot_y,
-      gnatw_dot_z,
-      gnatw_underscore_a,
-      gnatw_underscore_c,
-      gnatw_underscore_j,
-      gnatw_underscore_l,
-      gnatw_underscore_p,
-      gnatw_underscore_q,
-      gnatw_underscore_r,
-      gnatw_underscore_s,
-      gnaty,
-      gnatya,
-      gnatyb,
-      gnatyc,
-      gnatyd,
-      gnatye,
-      gnatyf,
-      gnatyh,
-      gnatyi,
-      gnatyk,
-      gnatyl,
-      gnatym,
-      gnatyn,
-      gnatyo,
-      gnatyp,
-      gnatyr,
-      gnatys,
-      gnatyu,
-      gnatyx,
-      gnatyz,
-      gnatyaa,
-      gnatybb,
-      gnatycc,
-      gnatydd,
-      gnatyii,
-      gnatyll,
-      gnatymm,
-      gnatyoo,
-      gnatyss,
-      gnatytt,
-      gnatel
-   );
-
-   subtype Active_Switch_Id is Switch_Id range gnatwb .. gnatel;
-
-   type Switch_Type is record
-
-      Status : Status_Type := Active;
-      --  The status will indicate whether the switch is currently active,
-      --  or has been deprecated. A deprecated switch will not control
-      --  diagnostics, and will not be emitted by the GNAT usage.
-
-      Human_Id : String_Ptr := null;
-      --  The Human_Id will be a unique and stable string-based ID which
-      --  identifies the content of the switch within the switch registry.
-      --  This ID will appear in SARIF readers.
-
-      Short_Name : String_Ptr := null;
-      --  The Short_Name will denote the -gnatXX name of the switch.
-
-      Description : String_Ptr := null;
-      --  The description will contain the description of the switch, as it is
-      --  currently emitted by the GNAT usage.
-
-      Documentation_Url : String_Ptr := null;
-      --  The documentation_url will point to the AdaCore documentation site
-      --  for the switch.
-
-   end record;
-
-   function Get_Switch (Id : Switch_Id) return Switch_Type;
-
-   function Get_Switch_Id (Name : String) return Switch_Id;
-
-   procedure Print_Switch_Repository;
-
-end Errsw;
diff --git a/gcc/ada/errutil.adb b/gcc/ada/errutil.adb
index b3674a1bcb50..3d5e392c4fba 100644
--- a/gcc/ada/errutil.adb
+++ b/gcc/ada/errutil.adb
@@ -27,7 +27,6 @@ with Atree;    use Atree;
 with Err_Vars; use Err_Vars;
 with Errid;    use Errid;
 with Erroutc;  use Erroutc;
-with Errsw;    use Errsw;
 with Namet;    use Namet;
 with Opt;      use Opt;
 with Output;   use Output;
diff --git a/gcc/ada/gcc-interface/Make-lang.in 
b/gcc/ada/gcc-interface/Make-lang.in
index 00a788b9277d..837aee9b2a7e 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -330,11 +330,12 @@ GNAT_ADA_OBJS =   \
  ada/elists.o  \
  ada/err_vars.o        \
  ada/errid.o \
+ ada/errid-diagnostic_repository.o \
+ ada/errid-switch_repository.o \
  ada/errout.o  \
  ada/erroutc.o \
  ada/erroutc-pretty_emitter.o \
  ada/erroutc-sarif_emitter.o \
- ada/errsw.o \
  ada/eval_fat.o        \
  ada/exp_aggr.o        \
  ada/exp_spark.o       \
@@ -621,11 +622,12 @@ GNATBIND_OBJS = \
  ada/elists.o     \
  ada/err_vars.o   \
  ada/errid.o      \
+ ada/errid-diagnostic_repository.o \
+ ada/errid-switch_repository.o \
  ada/errout.o     \
  ada/erroutc.o    \
  ada/erroutc-sarif_emitter.o \
  ada/erroutc-pretty_emitter.o \
- ada/errsw.o      \
  ada/exit.o       \
  ada/final.o      \
  ada/fmap.o       \
diff --git a/gcc/ada/gcc-interface/Makefile.in 
b/gcc/ada/gcc-interface/Makefile.in
index 881548358fc0..c0e9b2775f2e 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -331,7 +331,8 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o aspects.o 
s-casuti.o alloc.o \
  uname.o urealp.o usage.o widechar.o warnsw.o \
  seinfo.o einfo-entities.o einfo-utils.o sinfo-nodes.o sinfo-utils.o \
  errid.o \
- errsw.o \
+ errid-diagnostic_repository.o \
+ errid-switch_repository.o \
  erroutc-pretty_emitter.o \
  erroutc-sarif_emitter.o \
  json_utils.o
diff --git a/gcc/ada/par-endh.adb b/gcc/ada/par-endh.adb
index 8637e07238b6..ce32faf2e34c 100644
--- a/gcc/ada/par-endh.adb
+++ b/gcc/ada/par-endh.adb
@@ -23,7 +23,7 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Errid; use Errid;
+with Errid;    use Errid;
 with Namet.Sp; use Namet.Sp;
 with Stringt;  use Stringt;
 with Uintp;    use Uintp;

Reply via email to