aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/errout.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/errout.adb')
-rw-r--r--gcc/ada/errout.adb917
1 files changed, 439 insertions, 478 deletions
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 23c6b88..25d1d52 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -33,15 +33,18 @@ with Atree; use Atree;
with Casing; use Casing;
with Csets; use Csets;
with Debug; use Debug;
-with Diagnostics.Converter; use Diagnostics.Converter;
with Einfo; use Einfo;
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 Gnatvsn; use Gnatvsn;
with Lib; use Lib;
with Opt; use Opt;
with Nlists; use Nlists;
+with Osint; use Osint;
with Output; use Output;
with Scans; use Scans;
with Sem_Aux; use Sem_Aux;
@@ -97,10 +100,14 @@ package body Errout is
-----------------------
procedure Error_Msg_Internal
- (Msg : String;
- Span : Source_Span;
- Opan : Source_Span;
- Msg_Cont : Boolean);
+ (Msg : String;
+ Span : Source_Span;
+ Opan : Source_Span;
+ Msg_Cont : Boolean;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes);
-- This is the low-level routine used to post messages after dealing with
-- the issue of messages placed on instantiations (which get broken up
-- into separate calls in Error_Msg). Span is the location on which the
@@ -285,6 +292,115 @@ package body Errout is
end loop;
end Delete_Warning_And_Continuations;
+ ------------------
+ -- Labeled_Span --
+ ------------------
+
+ function Labeled_Span
+ (Span : Source_Span;
+ Label : String := "";
+ Is_Primary : Boolean := True;
+ Is_Region : Boolean := False)
+ return Labeled_Span_Type
+ is
+ L : Labeled_Span_Type;
+ begin
+ L.Span := Span;
+ if Label /= "" then
+ L.Label := new String'(Label);
+ end if;
+ L.Is_Primary := Is_Primary;
+ L.Is_Region := Is_Region;
+ L.Next := No_Labeled_Span;
+
+ return L;
+ end Labeled_Span;
+
+ --------------------------
+ -- Primary_Labeled_Span --
+ --------------------------
+
+ function Primary_Labeled_Span
+ (Span : Source_Span;
+ Label : String := "") return Labeled_Span_Type
+ is
+ begin
+ return Labeled_Span (Span => Span, Label => Label, Is_Primary => True);
+ end Primary_Labeled_Span;
+
+ --------------------------
+ -- Primary_Labeled_Span --
+ --------------------------
+
+ function Primary_Labeled_Span
+ (N : Node_Or_Entity_Id;
+ Label : String := "") return Labeled_Span_Type
+ is
+ begin
+ return Primary_Labeled_Span (To_Full_Span (N), Label);
+ end Primary_Labeled_Span;
+
+ ----------------------------
+ -- Secondary_Labeled_Span --
+ ----------------------------
+
+ function Secondary_Labeled_Span
+ (Span : Source_Span;
+ Label : String := "") return Labeled_Span_Type
+ is
+ begin
+ return Labeled_Span (Span => Span, Label => Label, Is_Primary => False);
+ end Secondary_Labeled_Span;
+
+ ----------------------------
+ -- Secondary_Labeled_Span --
+ ----------------------------
+
+ function Secondary_Labeled_Span
+ (N : Node_Or_Entity_Id;
+ Label : String := "") return Labeled_Span_Type
+ is
+ begin
+ return Secondary_Labeled_Span (To_Full_Span (N), Label);
+ end Secondary_Labeled_Span;
+
+ ----------
+ -- Edit --
+ ----------
+
+ function Edit (Text : String; Span : Source_Span) return Edit_Type is
+ begin
+ return (Text => new String'(Text), Span => Span, Next => No_Edit);
+ end Edit;
+
+ ---------
+ -- Fix --
+ ---------
+
+ function Fix (Description : String; Edits : Edit_Array) return Fix_Type is
+ First_Edit : Edit_Id := No_Edit;
+ Last_Edit : Edit_Id := No_Edit;
+ begin
+ for I in Edits'Range loop
+ Erroutc.Edits.Append (Edits (I));
+
+ if Last_Edit /= No_Edit then
+ Erroutc.Edits.Table (Last_Edit).Next := Erroutc.Edits.Last;
+ end if;
+ Last_Edit := Erroutc.Edits.Last;
+
+ -- Store the first element in the edit chain
+
+ if First_Edit = No_Edit then
+ First_Edit := Last_Edit;
+ end if;
+ end loop;
+
+ return (Description => new String'(Description),
+ Edits => First_Edit,
+ Next => No_Fix);
+ end Fix;
+
---------------
-- Error_Msg --
---------------
@@ -328,9 +444,13 @@ package body Errout is
end Error_Msg;
procedure Error_Msg
- (Msg : String;
- Flag_Span : Source_Span;
- N : Node_Id)
+ (Msg : String;
+ Flag_Span : Source_Span;
+ N : Node_Id;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes)
is
Flag_Location : constant Source_Ptr := Flag_Span.Ptr;
@@ -459,7 +579,15 @@ package body Errout is
-- Error_Msg_Internal to place the message in the requested location.
if Instantiation (Sindex) = No_Location then
- Error_Msg_Internal (Msg, Flag_Span, Flag_Span, False);
+ Error_Msg_Internal
+ (Msg => Msg,
+ Span => Flag_Span,
+ Opan => Flag_Span,
+ Msg_Cont => False,
+ Error_Code => Error_Code,
+ Label => Label,
+ Spans => Spans,
+ Fixes => Fixes);
return;
end if;
@@ -626,10 +754,14 @@ package body Errout is
-- Here we output the original message on the outer instantiation
Error_Msg_Internal
- (Msg => Msg,
- Span => To_Span (Actual_Error_Loc),
- Opan => Flag_Span,
- Msg_Cont => Msg_Cont_Status);
+ (Msg => Msg,
+ Span => To_Span (Actual_Error_Loc),
+ Opan => Flag_Span,
+ Msg_Cont => Msg_Cont_Status,
+ Error_Code => Error_Code,
+ Label => Label,
+ Spans => Spans,
+ Fixes => Fixes);
end;
end Error_Msg;
@@ -715,7 +847,7 @@ package body Errout is
-- error flag in this situation.
S1 := Prev_Token_Ptr;
- C := Source (S1);
+ C := Sinput.Source (S1);
-- If the previous token is a string literal, we need a special approach
-- since there may be white space inside the literal and we don't want
@@ -728,10 +860,10 @@ package body Errout is
loop
S1 := S1 + 1;
- if Source (S1) = C then
+ if Sinput.Source (S1) = C then
S1 := S1 + 1;
- exit when Source (S1) /= C;
- elsif Source (S1) in Line_Terminator then
+ exit when Sinput.Source (S1) /= C;
+ elsif Sinput.Source (S1) in Line_Terminator then
exit;
end if;
end loop;
@@ -749,10 +881,11 @@ package body Errout is
-- characters in this context, since this is only for error recovery.
else
- while Source (S1) not in Line_Terminator
- and then Source (S1) /= ' '
- and then Source (S1) /= ASCII.HT
- and then (Source (S1) /= '-' or else Source (S1 + 1) /= '-')
+ while Sinput.Source (S1) not in Line_Terminator
+ and then Sinput.Source (S1) /= ' '
+ and then Sinput.Source (S1) /= ASCII.HT
+ and then (Sinput.Source (S1) /= '-'
+ or else Sinput.Source (S1 + 1) /= '-')
and then S1 /= Token_Ptr
loop
S1 := S1 + 1;
@@ -785,8 +918,8 @@ package body Errout is
-- we would really like to place it in the "last" character of the tab
-- space, but that it too much trouble to worry about).
- elsif Source (Token_Ptr - 1) = ' '
- or else Source (Token_Ptr - 1) = ASCII.HT
+ elsif Sinput.Source (Token_Ptr - 1) = ' '
+ or else Sinput.Source (Token_Ptr - 1) = ASCII.HT
then
Error_Msg (Msg, Token_Ptr - 1);
@@ -842,13 +975,8 @@ package body Errout is
-----------------
procedure Error_Msg_F (Msg : String; N : Node_Id) is
- Fst, Lst : Node_Id;
begin
- First_And_Last_Nodes (N, Fst, Lst);
- Error_Msg_NEL (Msg, N, N,
- To_Span (Ptr => Sloc (Fst),
- First => First_Sloc (Fst),
- Last => Last_Sloc (Lst)));
+ Error_Msg_NEL (Msg, N, N, To_Full_Span_First (N));
end Error_Msg_F;
------------------
@@ -860,13 +988,8 @@ package body Errout is
N : Node_Id;
E : Node_Or_Entity_Id)
is
- Fst, Lst : Node_Id;
begin
- First_And_Last_Nodes (N, Fst, Lst);
- Error_Msg_NEL (Msg, N, E,
- To_Span (Ptr => Sloc (Fst),
- First => First_Sloc (Fst),
- Last => Last_Sloc (Lst)));
+ Error_Msg_NEL (Msg, N, E, To_Full_Span_First (N));
end Error_Msg_FE;
------------------------------
@@ -918,10 +1041,14 @@ package body Errout is
------------------------
procedure Error_Msg_Internal
- (Msg : String;
- Span : Source_Span;
- Opan : Source_Span;
- Msg_Cont : Boolean)
+ (Msg : String;
+ Span : Source_Span;
+ Opan : Source_Span;
+ Msg_Cont : Boolean;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes)
is
Sptr : constant Source_Ptr := Span.Ptr;
Optr : constant Source_Ptr := Opan.Ptr;
@@ -937,6 +1064,12 @@ package body Errout is
Warn_Err : Boolean;
-- Set if warning to be treated as error
+ First_Fix : Fix_Id := No_Fix;
+ Last_Fix : Fix_Id := No_Fix;
+
+ Primary_Loc : Labeled_Span_Id := No_Labeled_Span;
+ Last_Loc : Labeled_Span_Id := No_Labeled_Span;
+
procedure Handle_Serious_Error;
-- Internal procedure to do all error message handling for a serious
-- error message, other than bumping the error counts and arranging
@@ -1156,11 +1289,15 @@ package body Errout is
-- Remove (style) or info: at start of message
- if Msglen > 8 and then Msg_Buffer (1 .. 8) = "(style) " then
- M := 9;
+ if Msglen > Style_Prefix'Length
+ and then Msg_Buffer (1 .. Style_Prefix'Length) = Style_Prefix
+ then
+ M := Style_Prefix'Length + 1;
- elsif Msglen > 6 and then Msg_Buffer (1 .. 6) = "info: " then
- M := 7;
+ elsif Msglen > Info_Prefix'Length
+ and then Msg_Buffer (1 .. Info_Prefix'Length) = Info_Prefix
+ then
+ M := Info_Prefix'Length + 1;
else
M := 1;
@@ -1226,6 +1363,37 @@ package body Errout is
return;
end if;
+ if Continuation and then Has_Insertion_Line then
+ Erroutc.Locations.Append
+ (Primary_Labeled_Span (To_Span (Error_Msg_Sloc), Label));
+ else
+ Erroutc.Locations.Append (Primary_Labeled_Span (Span, Label));
+ end if;
+
+ Primary_Loc := Erroutc.Locations.Last;
+
+ Last_Loc := Primary_Loc;
+
+ for Span of Spans loop
+ Erroutc.Locations.Append (Span);
+ Erroutc.Locations.Table (Last_Loc).Next := Erroutc.Locations.Last;
+ Last_Loc := Erroutc.Locations.Last;
+ end loop;
+
+ for Fix of Fixes loop
+ Erroutc.Fixes.Append (Fix);
+ if Last_Fix /= No_Fix then
+ Erroutc.Fixes.Table (Last_Fix).Next := Erroutc.Fixes.Last;
+ end if;
+ Last_Fix := Erroutc.Fixes.Last;
+
+ -- Store the first element in the fix chain
+
+ if First_Fix = No_Fix then
+ First_Fix := Last_Fix;
+ end if;
+ end loop;
+
-- Here we build a new error object
Errors.Append
@@ -1245,7 +1413,12 @@ package body Errout is
Uncond => Is_Unconditional_Msg,
Msg_Cont => Continuation,
Deleted => False,
- Kind => Error_Msg_Kind));
+ Kind => Error_Msg_Kind,
+ Locations => Primary_Loc,
+ Id => Error_Code,
+ Switch =>
+ Get_Switch_Id (Error_Msg_Kind, Warning_Msg_Char),
+ Fixes => First_Fix));
Cur_Msg := Errors.Last;
-- Test if warning to be treated as error
@@ -1416,33 +1589,72 @@ package body Errout is
-- Error_Msg_N --
-----------------
- procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id) is
- Fst, Lst : Node_Id;
+ procedure Error_Msg_N
+ (Msg : String;
+ N : Node_Or_Entity_Id;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes)
+ is
begin
- First_And_Last_Nodes (N, Fst, Lst);
- Error_Msg_NEL (Msg, N, N,
- To_Span (Ptr => Sloc (N),
- First => First_Sloc (Fst),
- Last => Last_Sloc (Lst)));
+ Error_Msg_NEL
+ (Msg => Msg,
+ N => N,
+ E => N,
+ Flag_Span => To_Full_Span (N),
+ Error_Code => Error_Code,
+ Label => Label,
+ Spans => Spans,
+ Fixes => Fixes);
end Error_Msg_N;
+ ----------------------
+ -- Error_Msg_N_Gigi --
+ ----------------------
+
+ procedure Error_Msg_N_Gigi (Msg : String; N : Node_Or_Entity_Id) is
+ begin
+ Error_Msg_N (Msg, N);
+ end Error_Msg_N_Gigi;
+
------------------
-- Error_Msg_NE --
------------------
procedure Error_Msg_NE
+ (Msg : String;
+ N : Node_Or_Entity_Id;
+ E : Node_Or_Entity_Id;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes)
+ is
+ begin
+ Error_Msg_NEL
+ (Msg => Msg,
+ N => N,
+ E => E,
+ Flag_Span => To_Full_Span (N),
+ Error_Code => Error_Code,
+ Label => Label,
+ Spans => Spans,
+ Fixes => Fixes);
+ end Error_Msg_NE;
+
+ -----------------------
+ -- Error_Msg_NE_Gigi --
+ -----------------------
+
+ procedure Error_Msg_NE_Gigi
(Msg : String;
N : Node_Or_Entity_Id;
E : Node_Or_Entity_Id)
is
- Fst, Lst : Node_Id;
begin
- First_And_Last_Nodes (N, Fst, Lst);
- Error_Msg_NEL (Msg, N, E,
- To_Span (Ptr => Sloc (N),
- First => First_Sloc (Fst),
- Last => Last_Sloc (Lst)));
- end Error_Msg_NE;
+ Error_Msg_NE (Msg, N, E);
+ end Error_Msg_NE_Gigi;
-------------------
-- Error_Msg_NEL --
@@ -1465,10 +1677,14 @@ package body Errout is
end Error_Msg_NEL;
procedure Error_Msg_NEL
- (Msg : String;
- N : Node_Or_Entity_Id;
- E : Node_Or_Entity_Id;
- Flag_Span : Source_Span)
+ (Msg : String;
+ N : Node_Or_Entity_Id;
+ E : Node_Or_Entity_Id;
+ Flag_Span : Source_Span;
+ Error_Code : Diagnostic_Id := No_Diagnostic_Id;
+ Label : String := "";
+ Spans : Labeled_Span_Array := No_Locations;
+ Fixes : Fix_Array := No_Fixes)
is
begin
if Special_Msg_Delete (Msg, N, E) then
@@ -1502,7 +1718,14 @@ package body Errout is
then
Debug_Output (N);
Error_Msg_Node_1 := E;
- Error_Msg (Msg, Flag_Span, N);
+ Error_Msg
+ (Msg => Msg,
+ Flag_Span => Flag_Span,
+ N => N,
+ Error_Code => Error_Code,
+ Label => Label,
+ Spans => Spans,
+ Fixes => Fixes);
else
Last_Killed := True;
@@ -1522,17 +1745,12 @@ package body Errout is
Msg : String;
N : Node_Or_Entity_Id)
is
- Fst, Lst : Node_Id;
begin
if Eflag
and then In_Extended_Main_Source_Unit (N)
and then Comes_From_Source (N)
then
- First_And_Last_Nodes (N, Fst, Lst);
- Error_Msg_NEL (Msg, N, N,
- To_Span (Ptr => Sloc (N),
- First => First_Sloc (Fst),
- Last => Last_Sloc (Lst)));
+ Error_Msg_NEL (Msg, N, N, To_Full_Span (N));
end if;
end Error_Msg_NW;
@@ -2457,9 +2675,13 @@ package body Errout is
Write_Str (",""option"":""" & Option & """");
end if;
- -- Print message content
+ -- Print message content and ensure that the removed style prefix is
+ -- still in the message.
Write_Str (",""message"":""");
+ if Errors.Table (E).Kind = Style then
+ Write_JSON_Escaped_String (Style_Prefix);
+ end if;
Write_JSON_Escaped_String (Errors.Table (E).Text);
Write_Str ("""");
@@ -2502,109 +2724,21 @@ package body Errout is
procedure Write_Max_Errors;
-- Write message if max errors reached
- procedure Write_Source_Code_Lines
- (Span : Source_Span;
- SGR_Span : String);
- -- Write the source code line corresponding to Span, as follows when
- -- Span in on one line:
- --
- -- line | actual code line here with Span somewhere
- -- | ~~~~~^~~~
- --
- -- where the caret on the line points to location Span.Ptr, and the
- -- range Span.First..Span.Last is underlined.
- --
- -- or when the span is over multiple lines:
- --
- -- line | beginning of the Span on this line
- -- ... | ...
- -- line>| actual code line here with Span.Ptr somewhere
- -- ... | ...
- -- line | end of the Span on this line
- --
- -- or when the span is a simple location, as follows:
- --
- -- line | actual code line here with Span somewhere
- -- | ^ here
- --
- -- where the caret on the line points to location Span.Ptr
- --
- -- SGR_Span is the SGR string to start the section of code in the span,
- -- that should be closed with SGR_Reset.
-
--------------------
-- Emit_Error_Msgs --
---------------------
procedure Emit_Error_Msgs is
- Use_Prefix : Boolean;
- E : Error_Msg_Id;
+ E : Error_Msg_Id;
begin
Set_Standard_Error;
E := First_Error_Msg;
while E /= No_Error_Msg loop
-
- -- If -gnatdF is used, separate main messages from previous
- -- messages with a newline (unless it is an info message) and
- -- make continuation messages follow the main message with only
- -- an indentation of two space characters, without repeating
- -- file:line:col: prefix.
-
- Use_Prefix :=
- not (Debug_Flag_FF and then Errors.Table (E).Msg_Cont);
-
if not Errors.Table (E).Deleted then
-
- if Debug_Flag_FF then
- if Errors.Table (E).Msg_Cont then
- Write_Str (" ");
- elsif Errors.Table (E).Kind /= Info then
- Write_Eol;
- end if;
- end if;
-
- if Use_Prefix then
- Output_Msg_Location (E);
- end if;
-
+ Output_Msg_Location (E);
Output_Msg_Text (E);
Write_Eol;
-
- -- If -gnatdF is used, write the source code line
- -- corresponding to the location of the main message (unless
- -- it is an info message). Also write the source code line
- -- corresponding to an insertion location inside
- -- continuation messages.
-
- if Debug_Flag_FF
- and then Errors.Table (E).Kind /= Info
- then
- if Errors.Table (E).Msg_Cont then
- declare
- Loc : constant Source_Ptr :=
- Errors.Table (E).Insertion_Sloc;
- begin
- if Loc /= No_Location then
- Write_Source_Code_Lines
- (To_Span (Loc), SGR_Span => SGR_Note);
- end if;
- end;
-
- else
- declare
- SGR_Span : constant String :=
- (if Errors.Table (E).Kind = Info then SGR_Note
- elsif Errors.Table (E).Kind = Warning
- and then not Errors.Table (E).Warn_Err
- then SGR_Warning
- else SGR_Error);
- begin
- Write_Source_Code_Lines
- (Errors.Table (E).Optr, SGR_Span);
- end;
- end if;
- end if;
end if;
E := Errors.Table (E).Next;
@@ -2664,310 +2798,18 @@ package body Errout is
end if;
end Write_Max_Errors;
- -----------------------------
- -- Write_Source_Code_Lines --
- -----------------------------
-
- procedure Write_Source_Code_Lines
- (Span : Source_Span;
- SGR_Span : String)
- is
- function Get_Line_End
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr) return Source_Ptr;
- -- Get the source location for the end of the line in Buf for Loc. If
- -- Loc is past the end of Buf already, return Buf'Last.
-
- function Get_Line_Start
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr) return Source_Ptr;
- -- Get the source location for the start of the line in Buf for Loc
-
- function Image (X : Positive; Width : Positive) return String;
- -- Output number X over Width characters, with whitespace padding.
- -- Only output the low-order Width digits of X, if X is larger than
- -- Width digits.
-
- procedure Write_Buffer
- (Buf : Source_Buffer_Ptr;
- First : Source_Ptr;
- Last : Source_Ptr);
- -- Output the characters from First to Last position in Buf, using
- -- Write_Buffer_Char.
-
- procedure Write_Buffer_Char
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr);
- -- Output the characters at position Loc in Buf, translating ASCII.HT
- -- in a suitable number of spaces so that the output is not modified
- -- by starting in a different column that 1.
-
- procedure Write_Line_Marker
- (Num : Pos;
- Mark : Boolean;
- Width : Positive);
- -- Output the line number Num over Width characters, with possibly
- -- a Mark to denote the line with the main location when reporting
- -- a span over multiple lines.
-
- ------------------
- -- Get_Line_End --
- ------------------
-
- function Get_Line_End
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr) return Source_Ptr
- is
- Cur_Loc : Source_Ptr := Source_Ptr'Min (Loc, Buf'Last);
- begin
- while Cur_Loc < Buf'Last
- and then Buf (Cur_Loc) /= ASCII.LF
- loop
- Cur_Loc := Cur_Loc + 1;
- end loop;
-
- return Cur_Loc;
- end Get_Line_End;
-
- --------------------
- -- Get_Line_Start --
- --------------------
-
- function Get_Line_Start
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr) return Source_Ptr
- is
- Cur_Loc : Source_Ptr := Loc;
- begin
- while Cur_Loc > Buf'First
- and then Buf (Cur_Loc - 1) /= ASCII.LF
- loop
- Cur_Loc := Cur_Loc - 1;
- end loop;
-
- return Cur_Loc;
- end Get_Line_Start;
-
- -----------
- -- Image --
- -----------
-
- function Image (X : Positive; Width : Positive) return String is
- Str : String (1 .. Width);
- Curr : Natural := X;
- begin
- for J in reverse 1 .. Width loop
- if Curr > 0 then
- Str (J) := Character'Val (Character'Pos ('0') + Curr mod 10);
- Curr := Curr / 10;
- else
- Str (J) := ' ';
- end if;
- end loop;
-
- return Str;
- end Image;
-
- ------------------
- -- Write_Buffer --
- ------------------
-
- procedure Write_Buffer
- (Buf : Source_Buffer_Ptr;
- First : Source_Ptr;
- Last : Source_Ptr)
- is
- begin
- for Loc in First .. Last loop
- Write_Buffer_Char (Buf, Loc);
- end loop;
- end Write_Buffer;
-
- -----------------------
- -- Write_Buffer_Char --
- -----------------------
-
- procedure Write_Buffer_Char
- (Buf : Source_Buffer_Ptr;
- Loc : Source_Ptr)
- is
- begin
- -- If the character ASCII.HT is not the last one in the file,
- -- output as many spaces as the character represents in the
- -- original source file.
-
- if Buf (Loc) = ASCII.HT
- and then Loc < Buf'Last
- then
- for X in Get_Column_Number (Loc) ..
- Get_Column_Number (Loc + 1) - 1
- loop
- Write_Char (' ');
- end loop;
-
- -- Otherwise output the character itself
-
- else
- Write_Char (Buf (Loc));
- end if;
- end Write_Buffer_Char;
-
- -----------------------
- -- Write_Line_Marker --
- -----------------------
-
- procedure Write_Line_Marker
- (Num : Pos;
- Mark : Boolean;
- Width : Positive)
- is
- begin
- Write_Str (Image (Positive (Num), Width => Width));
- Write_Str ((if Mark then ">" else " ") & "|");
- end Write_Line_Marker;
-
- -- Local variables
-
- Loc : constant Source_Ptr := Span.Ptr;
- Line : constant Pos := Pos (Get_Physical_Line_Number (Loc));
-
- Col : constant Natural := Natural (Get_Column_Number (Loc));
-
- Fst : constant Source_Ptr := Span.First;
- Line_Fst : constant Pos :=
- Pos (Get_Physical_Line_Number (Fst));
- Col_Fst : constant Natural :=
- Natural (Get_Column_Number (Fst));
- Lst : constant Source_Ptr := Span.Last;
- Line_Lst : constant Pos :=
- Pos (Get_Physical_Line_Number (Lst));
- Col_Lst : constant Natural :=
- Natural (Get_Column_Number (Lst));
-
- Width : constant := 5;
- Buf : Source_Buffer_Ptr;
- Cur_Loc : Source_Ptr := Fst;
- Cur_Line : Pos := Line_Fst;
-
- -- Start of processing for Write_Source_Code_Lines
-
- begin
- if Loc >= First_Source_Ptr then
- Buf := Source_Text (Get_Source_File_Index (Loc));
-
- -- First line of the span with actual source code. We retrieve
- -- the beginning of the line instead of relying on Col_Fst, as
- -- ASCII.HT characters change column numbers by possibly more
- -- than one.
-
- Write_Line_Marker
- (Cur_Line,
- Line_Fst /= Line_Lst and then Cur_Line = Line,
- Width);
- Write_Buffer (Buf, Get_Line_Start (Buf, Cur_Loc), Cur_Loc - 1);
-
- -- Output the first/caret/last lines of the span, as well as
- -- lines that are directly above/below the caret if they complete
- -- the gap with first/last lines, otherwise use ... to denote
- -- intermediate lines.
-
- -- If the span is on one line and not a simple source location,
- -- color it appropriately.
-
- if Line_Fst = Line_Lst
- and then Col_Fst /= Col_Lst
- then
- Write_Str (SGR_Span);
- end if;
-
- declare
- function Do_Write_Line (Cur_Line : Pos) return Boolean is
- (Cur_Line in Line_Fst | Line | Line_Lst
- or else
- (Cur_Line = Line_Fst + 1 and then Cur_Line = Line - 1)
- or else
- (Cur_Line = Line + 1 and then Cur_Line = Line_Lst - 1));
- begin
- while Cur_Loc <= Buf'Last
- and then Cur_Loc <= Lst
- loop
- if Do_Write_Line (Cur_Line) then
- Write_Buffer_Char (Buf, Cur_Loc);
- end if;
-
- if Buf (Cur_Loc) = ASCII.LF then
- Cur_Line := Cur_Line + 1;
-
- -- Output ... for skipped lines
-
- if (Cur_Line = Line
- and then not Do_Write_Line (Cur_Line - 1))
- or else
- (Cur_Line = Line + 1
- and then not Do_Write_Line (Cur_Line))
- then
- Write_Str ((1 .. Width - 3 => ' ') & "... | ...");
- Write_Eol;
- end if;
-
- -- Display the line marker if the line should be
- -- displayed.
-
- if Do_Write_Line (Cur_Line) then
- Write_Line_Marker
- (Cur_Line,
- Line_Fst /= Line_Lst and then Cur_Line = Line,
- Width);
- end if;
- end if;
-
- Cur_Loc := Cur_Loc + 1;
- end loop;
- end;
-
- if Line_Fst = Line_Lst
- and then Col_Fst /= Col_Lst
- then
- Write_Str (SGR_Reset);
- end if;
-
- -- Output the rest of the last line of the span
-
- Write_Buffer (Buf, Cur_Loc, Get_Line_End (Buf, Cur_Loc));
-
- -- If the span is on one line, output a second line with caret
- -- sign pointing to location Loc
-
- if Line_Fst = Line_Lst then
- Write_Str (String'(1 .. Width => ' '));
- Write_Str (" |");
- Write_Str (String'(1 .. Col_Fst - 1 => ' '));
-
- Write_Str (SGR_Span);
-
- Write_Str (String'(Col_Fst .. Col - 1 => '~'));
- Write_Str ("^");
- Write_Str (String'(Col + 1 .. Col_Lst => '~'));
-
- -- If the span is really just a location, add the word "here"
- -- to clarify this is the location for the message.
-
- if Col_Fst = Col_Lst then
- Write_Str (" here");
- end if;
-
- Write_Str (SGR_Reset);
-
- Write_Eol;
- end if;
- end if;
- end Write_Source_Code_Lines;
-
-- Local variables
E : Error_Msg_Id;
Err_Flag : Boolean;
+ 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";
+
+ Dummy : Boolean;
+
-- Start of processing for Output_Messages
begin
@@ -3039,15 +2881,72 @@ package body Errout is
-- Use updated diagnostic mechanism
- if Debug_Flag_Underscore_DD then
- Convert_Errors_To_Diagnostics;
+ if Opt.SARIF_Output then
+ Set_Standard_Error;
+ Erroutc.SARIF_Emitter.Print_SARIF_Report;
+ Set_Standard_Output;
+
+ elsif Opt.SARIF_File then
+ System.OS_Lib.Delete_File (Sarif_File_Name, Dummy);
+ declare
+ Output_FD :
+ constant System.OS_Lib.File_Descriptor :=
+ System.OS_Lib.Create_New_File
+ (Sarif_File_Name, Fmode => System.OS_Lib.Text);
- Emit_Diagnostics;
+ begin
+ Set_Output (Output_FD);
+ Erroutc.SARIF_Emitter.Print_SARIF_Report;
+ Set_Standard_Output;
+ System.OS_Lib.Close (Output_FD);
+ end;
+ elsif Debug_Flag_FF then
+ Erroutc.Pretty_Emitter.Print_Error_Messages;
else
Emit_Error_Msgs;
end if;
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
+
+ System.OS_Lib.Delete_File (Diagnostics_File_Name, Dummy);
+ declare
+ Output_FD : constant System.OS_Lib.File_Descriptor :=
+ System.OS_Lib.Create_New_File
+ (Diagnostics_File_Name,
+ Fmode => System.OS_Lib.Text);
+
+ begin
+ Set_Output (Output_FD);
+
+ Print_Diagnostic_Repository;
+
+ Set_Standard_Output;
+
+ System.OS_Lib.Close (Output_FD);
+ end;
+ end if;
+
-- Full source listing case
if Full_List then
@@ -4056,17 +3955,45 @@ package body Errout is
Msglen := 0;
Flag_Source := Get_Source_File_Index (Flag);
- -- Skip info: at start, we have recorded this in Error_Msg_Kind, and
- -- this will be used (Info field in error message object) to put back
- -- the string when it is printed. We need to do this, or we get confused
+ P := Text'First;
+
+ -- Skip the continuation symbols at the start
+
+ if P <= Text'Last and then Text (P) = '\' then
+ Continuation := True;
+ P := P + 1;
+
+ if P <= Text'Last and then Text (P) = '\' then
+ Continuation_New_Line := True;
+ P := P + 1;
+ end if;
+ end if;
+
+ -- Skip the message kind tokens at start since it is recorded
+ -- in Error_Msg_Kind, and this will be used to put back the string when
+ -- it is printed. We need to do this, or we get confused
-- with instantiation continuations.
- if Text'Length > 6
- and then Text (Text'First .. Text'First + 5) = "info: "
+ if Text'Length > P + Info_Prefix'Length - 1
+ and then Text (P .. P + Info_Prefix'Length - 1) = Info_Prefix
then
- P := Text'First + 6;
- else
- P := Text'First;
+ P := P + Info_Prefix'Length;
+ elsif Text'Length > P + Style_Prefix'Length - 1
+ and then Text (P .. P + Style_Prefix'Length - 1) = Style_Prefix
+ then
+ P := P + Style_Prefix'Length;
+ elsif Text'Length > P + High_Prefix'Length - 1
+ and then Text (P .. P + High_Prefix'Length - 1) = High_Prefix
+ then
+ P := P + High_Prefix'Length;
+ elsif Text'Length > P + Medium_Prefix'Length - 1
+ and then Text (P .. P + Medium_Prefix'Length - 1) = Medium_Prefix
+ then
+ P := P + Medium_Prefix'Length;
+ elsif Text'Length > P + Low_Prefix'Length - 1
+ and then Text (P .. P + Low_Prefix'Length - 1) = Low_Prefix
+ then
+ P := P + Low_Prefix'Length;
end if;
-- Loop through characters of message
@@ -4109,14 +4036,6 @@ package body Errout is
when '#' =>
Set_Msg_Insertion_Line_Number (Error_Msg_Sloc, Flag);
- when '\' =>
- Continuation := True;
-
- if P <= Text'Last and then Text (P) = '\' then
- Continuation_New_Line := True;
- P := P + 1;
- end if;
-
when '@' =>
Set_Msg_Insertion_Column;
@@ -4372,6 +4291,48 @@ package body Errout is
end if;
end SPARK_Msg_NE;
+ ------------------
+ -- To_Full_Span --
+ ------------------
+
+ function To_Full_Span (N : Node_Id) return Source_Span is
+ Fst, Lst : Node_Id;
+ begin
+ First_And_Last_Nodes (N, Fst, Lst);
+ return To_Span (Ptr => Sloc (N),
+ First => First_Sloc (Fst),
+ Last => Last_Sloc (Lst));
+ end To_Full_Span;
+
+ ------------------------
+ -- To_Full_Span_First --
+ ------------------------
+
+ function To_Full_Span_First (N : Node_Id) return Source_Span is
+ Fst, Lst : Node_Id;
+ begin
+ First_And_Last_Nodes (N, Fst, Lst);
+ return To_Span (Ptr => Sloc (Fst),
+ First => First_Sloc (Fst),
+ Last => Last_Sloc (Lst));
+ end To_Full_Span_First;
+
+ -------------
+ -- To_Name --
+ -------------
+
+ function To_Name (E : Entity_Id) return String is
+ begin
+ -- The name of the node operator "&" has many special cases. Reuse the
+ -- node to name conversion implementation from the errout package for
+ -- now.
+
+ Error_Msg_Node_1 := E;
+ Set_Msg_Text ("&", Sloc (E));
+
+ return Msg_Buffer (1 .. Msglen);
+ end To_Name;
+
--------------------------
-- Unwind_Internal_Type --
--------------------------