aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sprint.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sprint.adb')
-rw-r--r--gcc/ada/sprint.adb306
1 files changed, 296 insertions, 10 deletions
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index 58e61df..08e6cf8 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -193,7 +193,7 @@ package body Sprint is
-- declarations that can have discriminants.
procedure Write_Ekind (E : Entity_Id);
- -- Write the String corresponding to the Ekind without "E_".
+ -- Write the String corresponding to the Ekind without "E_"
procedure Write_Id (N : Node_Id);
-- N is a node with a Chars field. This procedure writes the name that
@@ -203,7 +203,8 @@ package body Sprint is
-- the name associated with the entity (since it may have been encoded).
-- One other special case is that an entity has an active external name
-- (i.e. an external name present with no address clause), then this
- -- external name is output.
+ -- external name is output. This procedure also deals with outputting
+ -- declarations of referenced itypes, if not output earlier.
function Write_Identifiers (Node : Node_Id) return Boolean;
-- Handle node where the grammar has a list of defining identifiers, but
@@ -238,6 +239,10 @@ package body Sprint is
-- the Sloc of the current node is set to the first non-blank character
-- in the string S.
+ procedure Write_Itype (Typ : Entity_Id);
+ -- If Typ is an Itype that has not been written yet, write it. If Typ is
+ -- any other kind of entity or tree node, the call is ignored.
+
procedure Write_Name_With_Col_Check (N : Name_Id);
-- Write name (using Write_Name) with initial column check, and possible
-- initial Write_Indent (to get new line) if current line is too full.
@@ -272,6 +277,11 @@ package body Sprint is
-- Like Write_Str_WIth_Col_Check, but sets debug Sloc of current debug
-- node to first non-blank character if a current debug node is active.
+ procedure Write_Uint_With_Col_Check (U : Uint; Format : UI_Format);
+ -- Write Uint (using UI_Write) with initial column check, and possible
+ -- initial Write_Indent (to get new line) if current line is too full.
+ -- The format parameter determines the output format (see UI_Write).
+
procedure Write_Uint_With_Col_Check_Sloc (U : Uint; Format : UI_Format);
-- Write Uint (using UI_Write) with initial column check, and possible
-- initial Write_Indent (to get new line) if current line is too full.
@@ -417,7 +427,7 @@ package body Sprint is
Write_Eol;
end Underline;
- -- Start of processing for Tree_Dump.
+ -- Start of processing for Tree_Dump
begin
Dump_Generated_Only := Debug_Flag_G or
@@ -1078,7 +1088,6 @@ package body Sprint is
Condition : constant Node_Id := First (Expressions (Node));
Then_Expr : constant Node_Id := Next (Condition);
Else_Expr : constant Node_Id := Next (Then_Expr);
-
begin
Write_Str_With_Col_Check_Sloc ("(if ");
Sprint_Node (Condition);
@@ -2344,7 +2353,6 @@ package body Sprint is
declare
Alt_Node : Node_Id;
-
begin
Alt_Node := First (Select_Alternatives (Node));
loop
@@ -2607,7 +2615,6 @@ package body Sprint is
declare
Node1 : Node_Id;
-
begin
Node1 := First (Subtype_Marks (Node));
loop
@@ -2808,9 +2815,7 @@ package body Sprint is
if Dump_Original_Only then
N := First (List);
-
while Present (N) loop
-
if not Is_Rewrite_Insertion (N) then
Node_Exists := True;
exit;
@@ -2944,6 +2949,19 @@ package body Sprint is
procedure Write_Id (N : Node_Id) is
begin
+ -- Deal with outputting Itype
+
+ -- Note: if we are printing the full tree with -gnatds, then we may
+ -- end up picking up the Associated_Node link from a generic template
+ -- here which overlaps the Entity field, but as documented, Write_Itype
+ -- is defended against junk calls.
+
+ if Nkind (N) in N_Entity then
+ Write_Itype (N);
+ elsif Nkind (N) in N_Has_Entity then
+ Write_Itype (Entity (N));
+ end if;
+
-- Case of a defining identifier
if Nkind (N) = N_Defining_Identifier then
@@ -3022,7 +3040,6 @@ package body Sprint is
Write_Str_With_Col_Check (" (");
Ind := First_Index (E);
-
while Present (Ind) loop
Sprint_Node (Ind);
Next_Index (Ind);
@@ -3153,6 +3170,266 @@ package body Sprint is
Write_Str_Sloc (S);
end Write_Indent_Str_Sloc;
+ -----------------
+ -- Write_Itype --
+ -----------------
+
+ procedure Write_Itype (Typ : Entity_Id) is
+
+ procedure Write_Header (T : Boolean := True);
+ -- Write type if T is True, subtype if T is false
+
+ ------------------
+ -- Write_Header --
+ ------------------
+
+ procedure Write_Header (T : Boolean := True) is
+ begin
+ if T then
+ Write_Str ("[type ");
+ else
+ Write_Str ("[subtype ");
+ end if;
+
+ Write_Name_With_Col_Check (Chars (Typ));
+ Write_Str (" is ");
+ end Write_Header;
+
+ -- Start of processing for Write_Itype
+
+ begin
+ if Nkind (Typ) in N_Entity
+ and then Is_Itype (Typ)
+ and then not Itype_Printed (Typ)
+ then
+ -- Itype to be printed
+
+ declare
+ B : constant Node_Id := Etype (Typ);
+ X : Node_Id;
+ P : constant Node_Id := Parent (Typ);
+
+ S : constant Saved_Output_Buffer := Save_Output_Buffer;
+ -- Save current output buffer
+
+ begin
+ -- Write indentation at start of line
+
+ for J in 1 .. Indent loop
+ Write_Char (' ');
+ end loop;
+
+ -- If we have a constructed declaration, print it
+
+ if Present (P) and then Nkind (P) in N_Declaration then
+
+ -- We must set Itype_Printed true before the recursive call to
+ -- print the node, otherwise we get an infinite recursion!
+
+ Set_Itype_Printed (Typ, True);
+
+ -- Write the declaration enclosed in [], avoiding new line
+ -- at start of declaration, and semicolon at end.
+
+ Write_Char ('[');
+ Indent_Annull_Flag := True;
+ Sprint_Node (P);
+ Write_Erase_Char (';');
+
+ -- If no constructed declaration, then we have to concoct the
+ -- source corresponding to the type entity that we have at hand.
+
+ else
+ case Ekind (Typ) is
+
+ -- Access types and subtypes
+
+ when Access_Kind =>
+ Write_Header (Ekind (Typ) = E_Access_Type);
+ Write_Str ("access ");
+
+ if Is_Access_Constant (Typ) then
+ Write_Str ("constant ");
+ elsif Can_Never_Be_Null (Typ) then
+ Write_Str ("not null ");
+ end if;
+
+ Write_Id (Directly_Designated_Type (Typ));
+
+ -- Array types and string types
+
+ when E_Array_Type | E_String_Type =>
+ Write_Header;
+ Write_Str ("array (");
+
+ X := First_Index (Typ);
+ loop
+ Sprint_Node (X);
+
+ if not Is_Constrained (Typ) then
+ Write_Str (" range <>");
+ end if;
+
+ Next_Index (X);
+ exit when No (X);
+ Write_Str (", ");
+ end loop;
+
+ Write_Str (") of ");
+ Sprint_Node (Component_Type (Typ));
+
+ -- Array subtypes and string subtypes
+
+ when E_Array_Subtype | E_String_Subtype =>
+ Write_Header (False);
+ Write_Id (Etype (Typ));
+ Write_Str (" (");
+
+ X := First_Index (Typ);
+ loop
+ Sprint_Node (X);
+ Next_Index (X);
+ exit when No (X);
+ Write_Str (", ");
+ end loop;
+
+ Write_Char (')');
+
+ -- Signed integer types, and modular integer subtypes
+
+ when E_Signed_Integer_Type |
+ E_Signed_Integer_Subtype |
+ E_Modular_Integer_Subtype =>
+
+ Write_Header (Ekind (Typ) = E_Signed_Integer_Type);
+
+ if Ekind (Typ) = E_Signed_Integer_Type then
+ Write_Str ("new ");
+ end if;
+
+ Write_Id (B);
+
+ -- Print bounds if not different from base type
+
+ declare
+ L : constant Node_Id := Type_Low_Bound (Typ);
+ H : constant Node_Id := Type_High_Bound (Typ);
+ LE : constant Node_Id := Type_Low_Bound (B);
+ HE : constant Node_Id := Type_High_Bound (B);
+
+ begin
+ if Nkind (L) = N_Integer_Literal
+ and then Nkind (H) = N_Integer_Literal
+ and then Nkind (LE) = N_Integer_Literal
+ and then Nkind (HE) = N_Integer_Literal
+ and then UI_Eq (Intval (L), Intval (LE))
+ and then UI_Eq (Intval (H), Intval (HE))
+ then
+ null;
+
+ else
+ Write_Str (" range ");
+ Sprint_Node (Type_Low_Bound (Typ));
+ Write_Str (" .. ");
+ Sprint_Node (Type_High_Bound (Typ));
+ end if;
+ end;
+
+ -- Modular integer types
+
+ when E_Modular_Integer_Type =>
+ Write_Header;
+ Write_Str (" mod ");
+ Write_Uint_With_Col_Check (Modulus (Typ), Auto);
+
+ -- Floating point types and subtypes
+
+ when E_Floating_Point_Type |
+ E_Floating_Point_Subtype =>
+
+ Write_Header (Ekind (Typ) = E_Floating_Point_Type);
+
+ if Ekind (Typ) = E_Floating_Point_Type then
+ Write_Str ("new ");
+ end if;
+
+ Write_Id (Etype (Typ));
+
+ if Digits_Value (Typ) /= Digits_Value (Etype (Typ)) then
+ Write_Str (" digits ");
+ Write_Uint_With_Col_Check
+ (Digits_Value (Typ), Decimal);
+ end if;
+
+ -- Print bounds if not different from base type
+
+ declare
+ L : constant Node_Id := Type_Low_Bound (Typ);
+ H : constant Node_Id := Type_High_Bound (Typ);
+ LE : constant Node_Id := Type_Low_Bound (B);
+ HE : constant Node_Id := Type_High_Bound (B);
+
+ begin
+ if Nkind (L) = N_Real_Literal
+ and then Nkind (H) = N_Real_Literal
+ and then Nkind (LE) = N_Real_Literal
+ and then Nkind (HE) = N_Real_Literal
+ and then UR_Eq (Realval (L), Realval (LE))
+ and then UR_Eq (Realval (H), Realval (HE))
+ then
+ null;
+
+ else
+ Write_Str (" range ");
+ Sprint_Node (Type_Low_Bound (Typ));
+ Write_Str (" .. ");
+ Sprint_Node (Type_High_Bound (Typ));
+ end if;
+ end;
+
+ -- Record subtypes
+
+ when E_Record_Subtype =>
+ Write_Header (False);
+ Write_Str ("record");
+ Indent_Begin;
+
+ declare
+ C : Entity_Id;
+ begin
+ C := First_Entity (Typ);
+ while Present (C) loop
+ Write_Indent;
+ Write_Id (C);
+ Write_Str (" : ");
+ Write_Id (Etype (C));
+ Next_Entity (C);
+ end loop;
+ end;
+
+ Indent_End;
+ Write_Indent_Str (" end record");
+
+ -- For all other Itypes, print ??? (fill in later)
+
+ when others =>
+ Write_Header (True);
+ Write_Str ("???");
+
+ end case;
+ end if;
+
+ -- Add terminating bracket and restore output buffer
+
+ Write_Char (']');
+ Write_Eol;
+ Restore_Output_Buffer (S);
+ end;
+
+ Set_Itype_Printed (Typ);
+ end if;
+ end Write_Itype;
+
-------------------------------
-- Write_Name_With_Col_Check --
-------------------------------
@@ -3167,7 +3444,6 @@ package body Sprint is
-- name by three dots (e.g. R7b becomes R...b).
if Debug_Flag_II and then Name_Buffer (1) in 'A' .. 'Z' then
-
J := 2;
while J < Name_Len loop
exit when Name_Buffer (J) not in 'A' .. 'Z';
@@ -3355,6 +3631,16 @@ package body Sprint is
end if;
end Write_Str_With_Col_Check_Sloc;
+ -------------------------------
+ -- Write_Uint_With_Col_Check --
+ -------------------------------
+
+ procedure Write_Uint_With_Col_Check (U : Uint; Format : UI_Format) is
+ begin
+ Col_Check (UI_Decimal_Digits_Hi (U));
+ UI_Write (U, Format);
+ end Write_Uint_With_Col_Check;
+
------------------------------------
-- Write_Uint_With_Col_Check_Sloc --
------------------------------------