aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/grt/grt-backtraces.adb65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/grt/grt-backtraces.adb b/src/grt/grt-backtraces.adb
index d365adacb..471a0a261 100644
--- a/src/grt/grt-backtraces.adb
+++ b/src/grt/grt-backtraces.adb
@@ -83,8 +83,58 @@ package body Grt.Backtraces is
return Str (Str'First + Ref'Length) = NUL;
end Is_Eq;
+ type Op_Assoc_Type is record
+ Enc : String (1 .. 2);
+ Op : String (1 .. 4);
+ end record;
+
+ type Op_Array_Type is array (Positive range <>) of Op_Assoc_Type;
+ Op_Assoc : constant Op_Array_Type :=
+ (("Eq", "= "),
+ ("Ne", "/= "),
+ ("Lt", "< "),
+ ("Le", "<= "),
+ ("Gt", "> "),
+ ("Ge", ">= "),
+ ("Pl", "+ "),
+ ("Mi", "- "),
+ ("Mu", "* "),
+ ("Di", "/ "),
+ ("Ex", "** "),
+ ("Cc", "& "),
+ ("Cd", "?? "),
+ ("Qe", "?= "),
+ ("Qi", "?/= "),
+ ("QL", "?< "),
+ ("Ql", "?<= "),
+ ("QG", "?> "),
+ ("Qg", "?>= "));
+
+ procedure Demangle_Op_Err (C1, C2 : Character) is
+ begin
+ for I in Op_Assoc'Range loop
+ declare
+ A : Op_Assoc_Type renames Op_Assoc (I);
+ begin
+ if A.Enc (1) = C1 and A.Enc (2) = C2 then
+ Put_Err ('"');
+ for J in A.Op'range loop
+ exit when A.Op (J) = ' ';
+ Put_Err (A.Op (J));
+ end loop;
+ Put_Err ('"');
+ return;
+ end if;
+ end;
+ end loop;
+ Put_Err ("OP");
+ Put_Err (C1);
+ Put_Err (C2);
+ end Demangle_Op_Err;
+
procedure Demangle_Err (Name : Ghdl_C_String)
is
+ subtype Digit is Character range '0' .. '9';
Last_Part : Natural;
Suffix : Ghdl_C_String;
Off : Natural;
@@ -92,6 +142,7 @@ package body Grt.Backtraces is
Is_Arch : Boolean;
begin
if Name (1) = '_' then
+ -- Recognize elaboration routine.
if Is_Eq (Name, "__ghdl_ELABORATE") then
Put_Err ("Elaboration of design");
return;
@@ -132,6 +183,7 @@ package body Grt.Backtraces is
and then Name (Off + 5) = '_'
and then Name (Off + 6) = '_'
then
+ -- Recognize '__ARCH' and replaces 'x__ARCH__y' by 'x(y)'.
Off := Off + 7;
Put_Err ('(');
Is_Arch := True;
@@ -140,9 +192,22 @@ package body Grt.Backtraces is
Put_Err (')');
Is_Arch := False;
end if;
+ -- Replaces '__' by '.'.
Put_Err ('.');
Off := Off + 1;
end if;
+ elsif C = 'O' then
+ if Name (Off) = 'P' then
+ -- __OPxx is an operator.
+ Demangle_Op_Err (Name (Off + 1), Name (Off + 2));
+ Off := Off + 3;
+ elsif Name (Off) in Digit then
+ -- overloading
+ loop
+ Off := Off + 1;
+ exit when Name (Off) not in Digit;
+ end loop;
+ end if;
else
Put_Err (C);
end if;