aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/debug.adb5
-rw-r--r--gcc/ada/exp_ch3.adb4
-rw-r--r--gcc/ada/exp_put_image.adb286
-rw-r--r--gcc/ada/freeze.adb1
-rw-r--r--gcc/ada/rtsfind.ads2
-rw-r--r--gcc/ada/sem_ch13.adb54
-rw-r--r--gcc/ada/sem_ch3.adb50
-rw-r--r--gcc/ada/sem_ch3.ads5
-rw-r--r--gcc/ada/sem_disp.adb4
-rw-r--r--gcc/ada/sem_util.adb143
-rw-r--r--gcc/ada/sem_util.ads25
11 files changed, 425 insertions, 154 deletions
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index 3f1fa55..978f333 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -164,7 +164,7 @@ package body Debug is
-- d_w
-- d_x Disable inline expansion of Image attribute for enumeration types
-- d_y
- -- d_z Enable Put_Image on tagged types
+ -- d_z
-- d_A Stop generation of ALI file
-- d_B Warn on build-in-place function calls
@@ -993,9 +993,6 @@ package body Debug is
-- d_x The compiler does not expand in line the Image attribute for user-
-- defined enumeration types and the standard boolean type.
- -- d_z Enable the default Put_Image on tagged types that are not
- -- predefined.
-
-- d_A Do not generate ALI files by setting Opt.Disable_ALI_File.
-- d_B Warn on build-in-place function calls. This allows users to
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 4dbaadd..ce6d294 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -10345,9 +10345,7 @@ package body Exp_Ch3 is
-- Spec of Put_Image
- if Enable_Put_Image (Tag_Typ)
- and then No (TSS (Tag_Typ, TSS_Put_Image))
- then
+ if Enable_Put_Image (Tag_Typ) then
Append_To (Res, Predef_Spec_Or_Body (Loc,
Tag_Typ => Tag_Typ,
Name => Make_TSS_Name (Tag_Typ, TSS_Put_Image),
diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb
index 33c72c3..3a9751b 100644
--- a/gcc/ada/exp_put_image.adb
+++ b/gcc/ada/exp_put_image.adb
@@ -23,13 +23,14 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
+with Csets; use Csets;
with Einfo; use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils; use Einfo.Utils;
with Exp_Tss; use Exp_Tss;
-with Exp_Util;
-with Debug; use Debug;
+with Exp_Util; use Exp_Util;
with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
@@ -49,9 +50,6 @@ with Uintp; use Uintp;
package body Exp_Put_Image is
- Tagged_Put_Image_Enabled : Boolean renames Debug_Flag_Underscore_Z;
- -- ???Set True to enable Put_Image for at least some tagged types
-
-----------------------
-- Local Subprograms --
-----------------------
@@ -649,32 +647,90 @@ package body Exp_Put_Image is
-- Loop through components, skipping all internal components,
-- which are not part of the value (e.g. _Tag), except that we
-- don't skip the _Parent, since we do want to process that
- -- recursively. If _Parent is an interface type, being abstract
- -- with no components there is no need to handle it.
+ -- recursively.
while Present (Item) loop
if Nkind (Item) in
N_Component_Declaration | N_Discriminant_Specification
- and then
- ((Chars (Defining_Identifier (Item)) = Name_uParent
- and then not Is_Interface
- (Etype (Defining_Identifier (Item))))
- or else
- not Is_Internal_Name (Chars (Defining_Identifier (Item))))
then
- if First_Time then
- First_Time := False;
- else
- Append_To (Result,
- Make_Procedure_Call_Statement (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Record_Between), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ if Chars (Defining_Identifier (Item)) = Name_uParent then
+ declare
+ Parent_Type : constant Entity_Id :=
+ Underlying_Type (Base_Type (
+ (Etype (Defining_Identifier (Item)))));
+
+ Parent_Aspect_Spec : constant Node_Id :=
+ Find_Aspect (Parent_Type, Aspect_Put_Image);
+
+ Parent_Type_Decl : constant Node_Id :=
+ Declaration_Node (Parent_Type);
+
+ Parent_Rdef : Node_Id :=
+ Type_Definition (Parent_Type_Decl);
+ begin
+ -- If parent type has an noninherited
+ -- explicitly-specified Put_Image aspect spec, then
+ -- display parent part by calling specified procedure,
+ -- and then use extension-aggregate syntax for the
+ -- remaining components as per RM 4.10(15/5);
+ -- otherwise, "look through" the parent component
+ -- to its components - we don't want the image text
+ -- to include mention of an "_parent" component.
+
+ if Present (Parent_Aspect_Spec) and then
+ Entity (Parent_Aspect_Spec) = Parent_Type
+ then
+ Append_Component_Attr
+ (Result, Defining_Identifier (Item));
+
+ -- Omit the " with " if no subsequent components.
+
+ if not Is_Null_Extension_Of
+ (Descendant => Typ,
+ Ancestor => Parent_Type)
+ then
+ Append_To (Result,
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of
+ (RTE (RE_Put_UTF_8), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S),
+ Make_String_Literal (Loc, " with "))));
+ end if;
+ else
+ if Nkind (Parent_Rdef) = N_Derived_Type_Definition
+ then
+ Parent_Rdef :=
+ Record_Extension_Part (Parent_Rdef);
+ end if;
+
+ if Present (Component_List (Parent_Rdef)) then
+ Append_List_To (Result,
+ Make_Component_List_Attributes
+ (Component_List (Parent_Rdef)));
+ end if;
+ end if;
+ end;
+
+ elsif not Is_Internal_Name
+ (Chars (Defining_Identifier (Item)))
+ then
+ if First_Time then
+ First_Time := False;
+ else
+ Append_To (Result,
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Record_Between), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
+ end if;
+
+ Append_To (Result, Make_Component_Name (Item));
+ Append_Component_Attr
+ (Result, Defining_Identifier (Item));
end if;
-
- Append_To (Result, Make_Component_Name (Item));
- Append_Component_Attr (Result, Defining_Identifier (Item));
end if;
Next (Item);
@@ -690,13 +746,35 @@ package body Exp_Put_Image is
function Make_Component_Name (C : Entity_Id) return Node_Id is
Name : constant Name_Id := Chars (Defining_Identifier (C));
+ pragma Assert (Name /= Name_uParent);
+
+ function To_Upper (S : String) return String;
+ -- Same as Ada.Characters.Handling.To_Upper, but withing
+ -- Ada.Characters.Handling seems to cause mailserver problems.
+
+ --------------
+ -- To_Upper --
+ --------------
+
+ function To_Upper (S : String) return String is
+ begin
+ return Result : String := S do
+ for Char of Result loop
+ Char := Fold_Upper (Char);
+ end loop;
+ end return;
+ end To_Upper;
+
+ -- Start of processing for Make_Component_Name
+
begin
return
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
Parameter_Associations => New_List
(Make_Identifier (Loc, Name_S),
- Make_String_Literal (Loc, Get_Name_String (Name) & " => ")));
+ Make_String_Literal (Loc,
+ To_Upper (Get_Name_String (Name)) & " => ")));
end Make_Component_Name;
Stms : constant List_Id := New_List;
@@ -707,38 +785,47 @@ package body Exp_Put_Image is
-- Start of processing for Build_Record_Put_Image_Procedure
begin
- Append_To (Stms,
- Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Record_Before), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ if Is_Null_Record_Type (Btyp, Ignore_Privacy => True) then
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S),
+ Make_String_Literal (Loc, "(NULL RECORD)"))));
+ else
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Record_Before), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
- -- Generate Put_Images for the discriminants of the type
+ -- Generate Put_Images for the discriminants of the type
- Append_List_To (Stms,
- Make_Component_Attributes (Discriminant_Specifications (Type_Decl)));
+ Append_List_To (Stms,
+ Make_Component_Attributes
+ (Discriminant_Specifications (Type_Decl)));
- Rdef := Type_Definition (Type_Decl);
+ Rdef := Type_Definition (Type_Decl);
- -- In the record extension case, the components we want, including the
- -- _Parent component representing the parent type, are to be found in
- -- the extension. We will process the _Parent component using the type
- -- of the parent.
+ -- In the record extension case, the components we want are to be
+ -- found in the extension (although we have to process the
+ -- _Parent component to find inherited components).
- if Nkind (Rdef) = N_Derived_Type_Definition then
- Rdef := Record_Extension_Part (Rdef);
- end if;
+ if Nkind (Rdef) = N_Derived_Type_Definition then
+ Rdef := Record_Extension_Part (Rdef);
+ end if;
- if Present (Component_List (Rdef)) then
- Append_List_To (Stms,
- Make_Component_List_Attributes (Component_List (Rdef)));
- end if;
+ if Present (Component_List (Rdef)) then
+ Append_List_To (Stms,
+ Make_Component_List_Attributes (Component_List (Rdef)));
+ end if;
- Append_To (Stms,
- Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Record_After), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Record_After), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
+ end if;
Pnam := Make_Put_Image_Name (Loc, Btyp);
Build_Put_Image_Proc (Loc, Btyp, Decl, Pnam, Stms);
@@ -843,9 +930,9 @@ package body Exp_Put_Image is
--
-- Put_Image on tagged types triggers some bugs.
- if Is_Remote_Types (Scope (Typ))
+ if Ada_Version < Ada_2022
+ or else Is_Remote_Types (Scope (Typ))
or else (Is_Tagged_Type (Typ) and then In_Predefined_Unit (Typ))
- or else (Is_Tagged_Type (Typ) and then not Tagged_Put_Image_Enabled)
then
return False;
end if;
@@ -952,7 +1039,7 @@ package body Exp_Put_Image is
-- For T'Image (X) Generate an Expression_With_Actions node:
--
-- do
- -- S : Buffer := New_Buffer;
+ -- S : Buffer;
-- U_Type'Put_Image (S, X);
-- Result : constant String := Get (S);
-- Destroy (S);
@@ -970,13 +1057,16 @@ package body Exp_Put_Image is
Object_Definition =>
New_Occurrence_Of (RTE (RE_Buffer_Type), Loc));
+ Image_Prefix : constant Node_Id :=
+ Duplicate_Subexpr (First (Expressions (N)));
+
Put_Im : constant Node_Id :=
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (U_Type, Loc),
Attribute_Name => Name_Put_Image,
Expressions => New_List (
New_Occurrence_Of (Sink_Entity, Loc),
- New_Copy_Tree (First (Expressions (N)))));
+ Image_Prefix));
Result_Entity : constant Entity_Id :=
Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('R'));
Result_Decl : constant Node_Id :=
@@ -989,12 +1079,86 @@ package body Exp_Put_Image is
Name => New_Occurrence_Of (RTE (RE_Get), Loc),
Parameter_Associations => New_List (
New_Occurrence_Of (Sink_Entity, Loc))));
- Image : constant Node_Id :=
- Make_Expression_With_Actions (Loc,
- Actions => New_List (Sink_Decl, Put_Im, Result_Decl),
- Expression => New_Occurrence_Of (Result_Entity, Loc));
+ Actions : List_Id;
+
+ function Put_String_Exp (String_Exp : Node_Id;
+ Wide_Wide : Boolean := False) return Node_Id;
+ -- Generate a call to evaluate a String (or Wide_Wide_String, depending
+ -- on the Wide_Wide Boolean parameter) expression and output it into
+ -- the buffer.
+
+ --------------------
+ -- Put_String_Exp --
+ --------------------
+
+ function Put_String_Exp (String_Exp : Node_Id;
+ Wide_Wide : Boolean := False) return Node_Id is
+ Put_Id : constant RE_Id :=
+ (if Wide_Wide then RE_Wide_Wide_Put else RE_Put_UTF_8);
+
+ -- We could build a nondispatching call here, but to make
+ -- that work we'd have to change Rtsfind spec to make available
+ -- corresponding callees out of Ada.Strings.Text_Buffers.Unbounded
+ -- (as opposed to from Ada.Strings.Text_Buffers). Seems simpler to
+ -- introduce a type conversion and leave it to the optimizer to
+ -- eliminate the dispatching. This does not *introduce* any problems
+ -- if a no-dispatching-allowed restriction is in effect, since we
+ -- are already in the middle of generating a call to T'Class'Image.
+
+ Sink_Exp : constant Node_Id :=
+ Make_Type_Conversion (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of
+ (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc),
+ Expression => New_Occurrence_Of (Sink_Entity, Loc));
+ begin
+ return
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (Put_Id), Loc),
+ Parameter_Associations => New_List (Sink_Exp, String_Exp));
+ end Put_String_Exp;
+
+ -- Start of processing for Build_Image_Call
+
begin
- return Image;
+ if Is_Class_Wide_Type (U_Type) then
+ -- Generate qualified-expression syntax; qualification name comes
+ -- from calling Ada.Tags.Wide_Wide_Expanded_Name.
+
+ declare
+ -- The copy of Image_Prefix will be evaluated before the
+ -- original, which is ok if no side effects are involved.
+
+ pragma Assert (Side_Effect_Free (Image_Prefix));
+
+ Specific_Type_Name : constant Node_Id :=
+ Put_String_Exp
+ (Make_Function_Call (Loc,
+ Name => New_Occurrence_Of
+ (RTE (RE_Wide_Wide_Expanded_Name), Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => Duplicate_Subexpr (Image_Prefix),
+ Attribute_Name => Name_Tag))),
+ Wide_Wide => True);
+
+ Qualification : constant Node_Id :=
+ Put_String_Exp (Make_String_Literal (Loc, "'"));
+ begin
+ Actions := New_List
+ (Sink_Decl,
+ Specific_Type_Name,
+ Qualification,
+ Put_Im,
+ Result_Decl);
+ end;
+ else
+ Actions := New_List (Sink_Decl, Put_Im, Result_Decl);
+ end if;
+
+ return Make_Expression_With_Actions (Loc,
+ Actions => Actions,
+ Expression => New_Occurrence_Of (Result_Entity, Loc));
end Build_Image_Call;
------------------------------
@@ -1023,7 +1187,7 @@ package body Exp_Put_Image is
-- Don't do it if type Root_Buffer_Type is unavailable in the runtime.
if not In_Predefined_Unit (Compilation_Unit)
- and then Tagged_Put_Image_Enabled
+ and then Ada_Version >= Ada_2022
and then Tagged_Seen
and then not No_Run_Time_Mode
and then RTE_Available (RE_Root_Buffer_Type)
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 21d24cd..fa16887 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -7591,6 +7591,7 @@ package body Freeze is
or else Is_TSS (Id, TSS_Stream_Output)
or else Is_TSS (Id, TSS_Stream_Read)
or else Is_TSS (Id, TSS_Stream_Write)
+ or else Is_TSS (Id, TSS_Put_Image)
or else Nkind (Original_Node (P)) =
N_Subprogram_Renaming_Declaration)
then
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index ad84e9e..6bec611 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -708,6 +708,7 @@ package Rtsfind is
RE_TK_Tagged, -- Ada.Tags
RE_TK_Task, -- Ada.Tags
RE_Unregister_Tag, -- Ada.Tags
+ RE_Wide_Wide_Expanded_Name, -- Ada.Tags
RE_Set_Specific_Handler, -- Ada.Task_Termination
RE_Specific_Handler, -- Ada.Task_Termination
@@ -2389,6 +2390,7 @@ package Rtsfind is
RE_TK_Tagged => Ada_Tags,
RE_TK_Task => Ada_Tags,
RE_Unregister_Tag => Ada_Tags,
+ RE_Wide_Wide_Expanded_Name => Ada_Tags,
RE_Set_Specific_Handler => Ada_Task_Termination,
RE_Specific_Handler => Ada_Task_Termination,
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index dcd5954..83d7d3c 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -5230,44 +5230,64 @@ package body Sem_Ch13 is
F := First_Formal (Subp);
- if No (F)
- or else Etype (F) /= Class_Wide_Type (RTE (RE_Root_Buffer_Type))
+ if No (F) then
+ return False;
+ end if;
+
+ if Base_Type (Etype (F))
+ /= Class_Wide_Type (RTE (RE_Root_Buffer_Type))
then
+ if Report then
+ Error_Msg_N
+ ("wrong type for Put_Image procedure''s first parameter",
+ Parameter_Type (Parent (F)));
+ end if;
+
return False;
end if;
- Next_Formal (F);
+ if Parameter_Mode (F) /= E_In_Out_Parameter then
+ if Report then
+ Error_Msg_N
+ ("wrong mode for Put_Image procedure''s first parameter",
+ Parent (F));
+ end if;
- if Parameter_Mode (F) /= E_In_Parameter then
return False;
end if;
+ Next_Formal (F);
+
Typ := Etype (F);
-- Verify that the prefix of the attribute and the local name for
-- the type of the formal match.
- if Typ /= Ent then
- return False;
- end if;
+ if Base_Type (Typ) /= Base_Type (Ent) then
+ if Report then
+ Error_Msg_N
+ ("wrong type for Put_Image procedure''s second parameter",
+ Parameter_Type (Parent (F)));
+ end if;
- if Present (Next_Formal (F)) then
return False;
+ end if;
- elsif not Is_Scalar_Type (Typ)
- and then not Is_First_Subtype (Typ)
- then
- if Report and not Is_First_Subtype (Typ) then
+ if Parameter_Mode (F) /= E_In_Parameter then
+ if Report then
Error_Msg_N
- ("subtype of formal in Put_Image operation must be a "
- & "first subtype", Parameter_Type (Parent (F)));
+ ("wrong mode for Put_Image procedure''s second parameter",
+ Parent (F));
end if;
return False;
+ end if;
- else
- return True;
+ if Present (Next_Formal (F)) then
+ return False;
end if;
+
+ return True;
end Has_Good_Profile;
-- Start of processing for Analyze_Put_Image_TSS_Definition
@@ -5386,7 +5406,7 @@ package body Sem_Ch13 is
if No (F)
or else Ekind (Etype (F)) /= E_Anonymous_Access_Type
- or else Designated_Type (Etype (F)) /=
+ or else Base_Type (Designated_Type (Etype (F))) /=
Class_Wide_Type (RTE (RE_Root_Stream_Type))
then
return False;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 7a24298..4250483 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -19013,56 +19013,6 @@ package body Sem_Ch3 is
return False;
end Is_EVF_Procedure;
- -----------------------
- -- Is_Null_Extension --
- -----------------------
-
- function Is_Null_Extension (T : Entity_Id) return Boolean is
- Type_Decl : constant Node_Id := Parent (Base_Type (T));
- Comp_List : Node_Id;
- Comp : Node_Id;
-
- begin
- if Nkind (Type_Decl) /= N_Full_Type_Declaration
- or else not Is_Tagged_Type (T)
- or else Nkind (Type_Definition (Type_Decl)) /=
- N_Derived_Type_Definition
- or else No (Record_Extension_Part (Type_Definition (Type_Decl)))
- then
- return False;
- end if;
-
- Comp_List :=
- Component_List (Record_Extension_Part (Type_Definition (Type_Decl)));
-
- if Present (Discriminant_Specifications (Type_Decl)) then
- return False;
-
- elsif Present (Comp_List)
- and then Is_Non_Empty_List (Component_Items (Comp_List))
- then
- Comp := First (Component_Items (Comp_List));
-
- -- Only user-defined components are relevant. The component list
- -- may also contain a parent component and internal components
- -- corresponding to secondary tags, but these do not determine
- -- whether this is a null extension.
-
- while Present (Comp) loop
- if Comes_From_Source (Comp) then
- return False;
- end if;
-
- Next (Comp);
- end loop;
-
- return True;
-
- else
- return True;
- end if;
- end Is_Null_Extension;
-
--------------------------
-- Is_Private_Primitive --
--------------------------
diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads
index dcd4a34..eedb98c 100644
--- a/gcc/ada/sem_ch3.ads
+++ b/gcc/ada/sem_ch3.ads
@@ -176,11 +176,6 @@ package Sem_Ch3 is
-- corresponding to that discriminant in the constraint that specifies its
-- value.
- function Is_Null_Extension (T : Entity_Id) return Boolean;
- -- Returns True if the tagged type T has an N_Full_Type_Declaration that
- -- is a null extension, meaning that it has an extension part without any
- -- components and does not have a known discriminant part.
-
function Is_Visible_Component
(C : Entity_Id;
N : Node_Id := Empty) return Boolean;
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 15b700fa..06c4b07 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -45,7 +45,6 @@ with Restrict; use Restrict;
with Rident; use Rident;
with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
-with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Eval; use Sem_Eval;
@@ -1209,7 +1208,7 @@ package body Sem_Disp is
-- primitives.
-- 3. Subprograms associated with stream attributes (built by
- -- New_Stream_Subprogram)
+ -- New_Stream_Subprogram) or with the Put_Image attribute.
-- 4. Wrappers built for inherited operations with inherited class-
-- wide conditions, where the conditions include calls to other
@@ -1238,6 +1237,7 @@ package body Sem_Disp is
or else Get_TSS_Name (Subp) = TSS_Stream_Read
or else Get_TSS_Name (Subp) = TSS_Stream_Write
+ or else Get_TSS_Name (Subp) = TSS_Put_Image
or else
(Is_Wrapper (Subp)
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index c0bc4b7..e5b76f3 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -712,7 +712,7 @@ package body Sem_Util is
return Make_Level_Literal
(Type_Access_Level (Etype (E)));
- -- A non-discriminant selected component where the component
+ -- A nondiscriminant selected component where the component
-- is an anonymous access type means that its associated
-- level is that of the containing type - see RM 3.10.2 (16).
@@ -18576,18 +18576,143 @@ package body Sem_Util is
return False;
end Is_Nontrivial_DIC_Procedure;
+ -----------------------
+ -- Is_Null_Extension --
+ -----------------------
+
+ function Is_Null_Extension
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
+ is
+ Type_Decl : Node_Id;
+ Type_Def : Node_Id;
+ begin
+ if Ignore_Privacy then
+ Type_Decl := Parent (Underlying_Type (Base_Type (T)));
+ else
+ Type_Decl := Parent (Base_Type (T));
+ if Nkind (Type_Decl) /= N_Full_Type_Declaration then
+ return False;
+ end if;
+ end if;
+ pragma Assert (Nkind (Type_Decl) = N_Full_Type_Declaration);
+ Type_Def := Type_Definition (Type_Decl);
+ if Present (Discriminant_Specifications (Type_Decl))
+ or else Nkind (Type_Def) /= N_Derived_Type_Definition
+ or else not Is_Tagged_Type (T)
+ or else No (Record_Extension_Part (Type_Def))
+ then
+ return False;
+ end if;
+
+ return Is_Null_Record_Definition (Record_Extension_Part (Type_Def));
+ end Is_Null_Extension;
+
+ --------------------------
+ -- Is_Null_Extension_Of --
+ --------------------------
+
+ function Is_Null_Extension_Of
+ (Descendant, Ancestor : Entity_Id) return Boolean
+ is
+ Ancestor_Type : constant Entity_Id
+ := Underlying_Type (Base_Type (Ancestor));
+ Descendant_Type : Entity_Id := Underlying_Type (Base_Type (Descendant));
+ begin
+ pragma Assert (Descendant_Type /= Ancestor_Type);
+ while Descendant_Type /= Ancestor_Type loop
+ if not Is_Null_Extension
+ (Descendant_Type, Ignore_Privacy => True)
+ then
+ return False;
+ end if;
+ Descendant_Type := Etype (Subtype_Indication
+ (Type_Definition (Parent (Descendant_Type))));
+ Descendant_Type := Underlying_Type (Base_Type (Descendant_Type));
+ end loop;
+ return True;
+ end Is_Null_Extension_Of;
+
+ -------------------------------
+ -- Is_Null_Record_Definition --
+ -------------------------------
+
+ function Is_Null_Record_Definition (Record_Def : Node_Id) return Boolean is
+ Item : Node_Id;
+ begin
+ -- Testing Null_Present is just an optimization, not required.
+
+ if Null_Present (Record_Def) then
+ return True;
+ elsif Present (Variant_Part (Component_List (Record_Def))) then
+ return False;
+ elsif not Present (Component_List (Record_Def)) then
+ return True;
+ end if;
+
+ Item := First (Component_Items (Component_List (Record_Def)));
+
+ while Present (Item) loop
+ if Nkind (Item) = N_Component_Declaration
+ and then Is_Internal_Name (Chars (Defining_Identifier (Item)))
+ then
+ null;
+ elsif Nkind (Item) = N_Pragma then
+ null;
+ else
+ return False;
+ end if;
+ Item := Next (Item);
+ end loop;
+
+ return True;
+ end Is_Null_Record_Definition;
+
-------------------------
-- Is_Null_Record_Type --
-------------------------
- function Is_Null_Record_Type (T : Entity_Id) return Boolean is
- Decl : constant Node_Id := Parent (T);
+ function Is_Null_Record_Type
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
+ is
+ Decl : Node_Id;
+ Type_Def : Node_Id;
begin
- return Nkind (Decl) = N_Full_Type_Declaration
- and then Nkind (Type_Definition (Decl)) = N_Record_Definition
- and then
- (No (Component_List (Type_Definition (Decl)))
- or else Null_Present (Component_List (Type_Definition (Decl))));
+ if not Is_Record_Type (T) then
+ return False;
+ end if;
+
+ if Ignore_Privacy then
+ Decl := Parent (Underlying_Type (Base_Type (T)));
+ else
+ Decl := Parent (Base_Type (T));
+ if Nkind (Decl) /= N_Full_Type_Declaration then
+ return False;
+ end if;
+ end if;
+ pragma Assert (Nkind (Decl) = N_Full_Type_Declaration);
+ Type_Def := Type_Definition (Decl);
+
+ if Has_Discriminants (Defining_Identifier (Decl)) then
+ return False;
+ end if;
+
+ case Nkind (Type_Def) is
+ when N_Record_Definition =>
+ return Is_Null_Record_Definition (Type_Def);
+ when N_Derived_Type_Definition =>
+ if not Is_Null_Record_Type
+ (Etype (Subtype_Indication (Type_Def)),
+ Ignore_Privacy => Ignore_Privacy)
+ then
+ return False;
+ elsif not Is_Tagged_Type (T) then
+ return True;
+ else
+ return Is_Null_Extension (T, Ignore_Privacy => Ignore_Privacy);
+ end if;
+ when others =>
+ return False;
+ end case;
end Is_Null_Record_Type;
---------------------
@@ -19183,7 +19308,7 @@ package body Sem_Util is
elsif Is_Tagged_Type (Typ) then
return True;
- -- Case of non-discriminated record
+ -- Case of nondiscriminated record
else
declare
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 10f1ba5..0894d03 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -2126,9 +2126,28 @@ package Sem_Util is
-- assertion expression of pragma Default_Initial_Condition and if it does,
-- the encapsulated expression is nontrivial.
- function Is_Null_Record_Type (T : Entity_Id) return Boolean;
- -- Determine whether T is declared with a null record definition or a
- -- null component list.
+ function Is_Null_Extension
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean;
+ -- Given a tagged type, returns True if argument is a type extension
+ -- that introduces no new components (discriminant or nondiscriminant).
+ -- Ignore_Privacy should be True for use in implementing dynamic semantics.
+
+ function Is_Null_Extension_Of
+ (Descendant, Ancestor : Entity_Id) return Boolean;
+ -- Given two tagged types, the first a descendant of the second,
+ -- returns True if every component of Descendant is inherited
+ -- (directly or indirectly) from Ancestor. Privacy is ignored.
+
+ function Is_Null_Record_Definition (Record_Def : Node_Id) return Boolean;
+ -- Returns True for an N_Record_Definition node that has no user-defined
+ -- components (and no variant part).
+
+ function Is_Null_Record_Type
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean;
+ -- Determine whether T is declared with a null record definition, a
+ -- null component list, or as a type derived from a null record type
+ -- (with a null extension if tagged). Returns True for interface types,
+ -- False for discriminated types.
function Is_Object_Image (Prefix : Node_Id) return Boolean;
-- Returns True if an 'Img, 'Image, 'Wide_Image, or 'Wide_Wide_Image