+2017-09-08 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_intr.adb (Append_Entity_Name): Move to ...
+ * sem_util.ads, sem_util.adb: ... here to share it.
+ (Subprogram_Name): New subprogram, to compute the name of the enclosing
+ subprogram/entity.
+ * errutil.adb (Error_Msg): Fill new field Node.
+ * erroutc.ads (Subprogram_Name_Ptr): New.
+ (Error_Msg_Object): New field Node.
+ * erroutc.adb (dmsg, Output_Msg_Text): Take new field Node into account.
+ * errout.adb (Error_Msg): New variant with node id parameter.
+ Fill new parameter Node when emitting messages. Revert previous
+ changes for Include_Subprogram_In_Messages.
+ * sem_ch5.adb (Check_Unreachable_Code): Supply Node parameter when
+ generating warning message.
+
+2017-09-08 Ed Schonberg <schonberg@adacore.com>
+
+ * par-ch4.adb (P_Iterated_Component_Association): Place construct
+ under -gnat2020 flag, given that it is a future feature of
+ the language.
+ * sem_aggr.adb (Resolve_Iterated_Component_Association): Mark
+ defining identifier as referenced to prevent spurious warnings:
+ corresponding loop is expanded into one or more loops whose
+ variable has the same name, and the expression uses those names
+ and not the original one.
+
2017-09-08 Hristian Kirtchev <kirtchev@adacore.com>
* sem_elab.adb (Check_A_Call): Do not consider
(Msg : String;
Sptr : Source_Ptr;
Optr : Source_Ptr;
- Msg_Cont : Boolean);
+ Msg_Cont : Boolean;
+ Node : Node_Id);
-- 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). Sptr is the location on which the
-- copy. So typically we can see Optr pointing to the template location
-- in an instantiation copy when Sptr points to the source location of
-- the actual instantiation (i.e the line with the new). Msg_Cont is
- -- set true if this is a continuation message.
+ -- set true if this is a continuation message. Node is the relevant
+ -- Node_Id for this message, to be used to compute the enclosing entity if
+ -- Opt.Include_Subprogram_In_Messages is set.
function No_Warnings (N : Node_Or_Entity_Id) return Boolean;
-- Determines if warnings should be suppressed for the given node
-- referencing the generic declaration.
procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is
+ begin
+ Error_Msg (Msg, Flag_Location, Empty);
+ end Error_Msg;
+
+ procedure Error_Msg
+ (Msg : String;
+ Flag_Location : Source_Ptr;
+ N : Node_Id)
+ is
Sindex : Source_File_Index;
-- Source index for flag location
-- Original location of Flag_Location (i.e. location in original
-- template in instantiation case, otherwise unchanged).
- Entity : Bounded_String;
-
begin
-- Return if all errors are to be ignored
Prescan_Message (Msg);
Orig_Loc := Original_Location (Flag_Location);
- if Include_Subprogram_In_Messages then
- declare
- Ent : constant Entity_Id := Current_Subprogram_Ptr.all;
- begin
- if Present (Ent) then
- Append_Unqualified_Decoded (Entity, Chars (Ent));
- else
- Append (Entity, "unknown subprogram");
- end if;
- end;
- end if;
-
-- If the current location is in an instantiation, the issue arises of
-- whether to post the message on the template or the instantiation.
-- Error_Msg_Internal to place the message in the requested location.
if Instantiation (Sindex) = No_Location then
- if Include_Subprogram_In_Messages then
- Append (Entity, ": ");
- Append (Entity, Msg);
- Error_Msg_Internal (+Entity, Flag_Location, Flag_Location, False);
- else
- Error_Msg_Internal (Msg, Flag_Location, Flag_Location, False);
- end if;
-
+ Error_Msg_Internal (Msg, Flag_Location, Flag_Location, False, N);
return;
end if;
if Inlined_Body (X) then
if Is_Info_Msg then
Error_Msg_Internal
- ("info: in inlined body #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "info: in inlined body #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
elsif Is_Warning_Msg then
Error_Msg_Internal
- (Warn_Insertion & "in inlined body #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => Warn_Insertion & "in inlined body #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
elsif Is_Style_Msg then
Error_Msg_Internal
- ("style: in inlined body #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "style: in inlined body #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
else
Error_Msg_Internal
- ("error in inlined body #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "error in inlined body #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
end if;
-- Case of generic instantiation
else
if Is_Info_Msg then
Error_Msg_Internal
- ("info: in instantiation #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "info: in instantiation #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
elsif Is_Warning_Msg then
Error_Msg_Internal
- (Warn_Insertion & "in instantiation #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => Warn_Insertion & "in instantiation #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
elsif Is_Style_Msg then
Error_Msg_Internal
- ("style: in instantiation #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "style: in instantiation #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
else
Error_Msg_Internal
- ("instantiation error #",
- Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
+ (Msg => "instantiation error #",
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
end if;
end if;
end if;
-- Here we output the original message on the outer instantiation
- if Include_Subprogram_In_Messages then
- Append (Entity, ": ");
- Append (Entity, Msg);
- Error_Msg_Internal
- (+Entity, Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
- else
- Error_Msg_Internal
- (Msg, Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
- end if;
+ Error_Msg_Internal
+ (Msg => Msg,
+ Sptr => Actual_Error_Loc,
+ Optr => Flag_Location,
+ Msg_Cont => Msg_Cont_Status,
+ Node => N);
end;
end Error_Msg;
(Msg : String;
Sptr : Source_Ptr;
Optr : Source_Ptr;
- Msg_Cont : Boolean)
+ Msg_Cont : Boolean;
+ Node : Node_Id)
is
Next_Msg : Error_Msg_Id;
-- Pointer to next message at insertion point
Serious => Is_Serious_Error,
Uncond => Is_Unconditional_Msg,
Msg_Cont => Continuation,
- Deleted => False));
+ Deleted => False,
+ Node => Node));
Cur_Msg := Errors.Last;
-- Test if warning to be treated as error
then
Debug_Output (N);
Error_Msg_Node_1 := E;
- Error_Msg (Msg, Flag_Location);
+ Error_Msg (Msg, Flag_Location, N);
else
Last_Killed := True;
-- error message tag. The -gnatw.d switch sets this flag True, -gnatw.D
-- sets this flag False.
- type Current_Subprogram_Type is access function return Entity_Id;
- Current_Subprogram_Ptr : Current_Subprogram_Type := null;
- -- Indirect call to Sem_Util.Current_Subprogram to break circular
- -- dependency with the static elaboration model.
-
-----------------------------------
-- Suppression of Error Messages --
-----------------------------------
-- Output list of messages, including messages giving number of detected
-- errors and warnings.
- procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr);
+ procedure Error_Msg
+ (Msg : String; Flag_Location : Source_Ptr);
+ procedure Error_Msg
+ (Msg : String; Flag_Location : Source_Ptr; N : Node_Id);
-- Output a message at specified location. Can be called from the parser
- -- or the semantic analyzer.
+ -- or the semantic analyzer. If N is set, points to the relevant node for
+ -- this message.
procedure Error_Msg_S (Msg : String);
-- Output a message at current scan pointer location. This routine can be
w (" Uncond = ", E.Uncond);
w (" Msg_Cont = ", E.Msg_Cont);
w (" Deleted = ", E.Deleted);
+ w (" Node = ", Int (E.Node));
Write_Eol;
end dmsg;
-- Postfix warning tag to message if needed
if Tag /= "" and then Warning_Doc_Switch then
- Txt := new String'(Text.all & ' ' & Tag);
+ if Include_Subprogram_In_Messages then
+ Txt :=
+ new String'
+ (Subprogram_Name_Ptr (Errors.Table (E).Node) &
+ ": " & Text.all & ' ' & Tag);
+ else
+ Txt := new String'(Text.all & ' ' & Tag);
+ end if;
+
+ elsif Include_Subprogram_In_Messages
+ and then (Errors.Table (E).Warn or else Errors.Table (E).Style)
+ then
+ Txt :=
+ new String'
+ (Subprogram_Name_Ptr (Errors.Table (E).Node) &
+ ": " & Text.all);
else
Txt := Text;
end if;
-- output. This is used for internal processing for the case of an
-- illegal instantiation. See Error_Msg routine for further details.
+ type Subprogram_Name_Type is access function (N : Node_Id) return String;
+ Subprogram_Name_Ptr : Subprogram_Name_Type;
+ -- Indirect call to Sem_Util.Subprogram_Name to break circular
+ -- dependency with the static elaboration model.
+
----------------------------
-- Message ID Definitions --
----------------------------
Deleted : Boolean;
-- If this flag is set, the message is not printed. This is used
-- in the circuit for deleting duplicate/redundant error messages.
+
+ Node : Node_Id;
+ -- If set, points to the node relevant for this message which will be
+ -- used to compute the enclosing subprogram name if
+ -- Opt.Include_Subprogram_In_Messages is set.
end record;
package Errors is new Table.Table (
Serious => Is_Serious_Error,
Uncond => Is_Unconditional_Msg,
Msg_Cont => Continuation,
- Deleted => False));
+ Deleted => False,
+ Node => Empty));
Cur_Msg := Errors.Last;
Prev_Msg := No_Error_Msg;
procedure Expand_Interface_Conversion (N : Node_Id) is
function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id;
- -- Return the underlying record type of Typ.
+ -- Return the underlying record type of Typ
----------------------------
-- Underlying_Record_Type --
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2017, 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- --
with Checks; use Checks;
with Einfo; use Einfo;
with Elists; use Elists;
-with Errout; use Errout;
with Expander; use Expander;
with Exp_Atag; use Exp_Atag;
with Exp_Ch4; use Exp_Ch4;
-- GNAT.Source_Info; see g-souinf.ads for documentation of these
-- intrinsics.
- procedure Append_Entity_Name (Buf : in out Bounded_String; E : Entity_Id);
- -- Recursive procedure to construct string for qualified name of enclosing
- -- program unit. The qualification stops at an enclosing scope has no
- -- source name (block or loop). If entity is a subprogram instance, skip
- -- enclosing wrapper package. The name is appended to Buf.
-
---------------------
-- Add_Source_Info --
---------------------
end case;
end Add_Source_Info;
- -----------------------
- -- Append_Entity_Name --
- -----------------------
-
- procedure Append_Entity_Name (Buf : in out Bounded_String; E : Entity_Id) is
- Temp : Bounded_String;
-
- procedure Inner (E : Entity_Id);
- -- Inner recursive routine, keep outer routine nonrecursive to ease
- -- debugging when we get strange results from this routine.
-
- -----------
- -- Inner --
- -----------
-
- procedure Inner (E : Entity_Id) is
- begin
- -- If entity has an internal name, skip by it, and print its scope.
- -- Note that we strip a final R from the name before the test; this
- -- is needed for some cases of instantiations.
-
- declare
- E_Name : Bounded_String;
-
- begin
- Append (E_Name, Chars (E));
-
- if E_Name.Chars (E_Name.Length) = 'R' then
- E_Name.Length := E_Name.Length - 1;
- end if;
-
- if Is_Internal_Name (E_Name) then
- Inner (Scope (E));
- return;
- end if;
- end;
-
- -- Just print entity name if its scope is at the outer level
-
- if Scope (E) = Standard_Standard then
- null;
-
- -- If scope comes from source, write scope and entity
-
- elsif Comes_From_Source (Scope (E)) then
- Append_Entity_Name (Temp, Scope (E));
- Append (Temp, '.');
-
- -- If in wrapper package skip past it
-
- elsif Is_Wrapper_Package (Scope (E)) then
- Append_Entity_Name (Temp, Scope (Scope (E)));
- Append (Temp, '.');
-
- -- Otherwise nothing to output (happens in unnamed block statements)
-
- else
- null;
- end if;
-
- -- Output the name
-
- declare
- E_Name : Bounded_String;
-
- begin
- Append_Unqualified_Decoded (E_Name, Chars (E));
-
- -- Remove trailing upper-case letters from the name (useful for
- -- dealing with some cases of internal names generated in the case
- -- of references from within a generic).
-
- while E_Name.Length > 1
- and then E_Name.Chars (E_Name.Length) in 'A' .. 'Z'
- loop
- E_Name.Length := E_Name.Length - 1;
- end loop;
-
- -- Adjust casing appropriately (gets name from source if possible)
-
- Adjust_Name_Case (E_Name, Sloc (E));
- Append (Temp, E_Name);
- end;
- end Inner;
-
- -- Start of processing for Append_Entity_Name
-
- begin
- Inner (E);
- Append (Buf, Temp);
- end Append_Entity_Name;
-
---------------------------------
-- Expand_Binary_Operator_Call --
---------------------------------
------------------------------------------
procedure Replace_Discriminals_Of_Protected_Op (Expr : Node_Id) is
- function Find_Corresponding_Discriminal (E : Entity_Id)
- return Entity_Id;
- -- Find the local entity that renames a discriminant of the
- -- enclosing protected type, and has a matching name.
+ function Find_Corresponding_Discriminal
+ (E : Entity_Id) return Entity_Id;
+ -- Find the local entity that renames a discriminant of the enclosing
+ -- protected type, and has a matching name.
+
+ function Replace_Discr_Ref (N : Node_Id) return Traverse_Result;
+ -- Replace a reference to a discriminant of the original protected
+ -- type by the local renaming declaration of the discriminant of
+ -- the target object.
------------------------------------
- -- find_Corresponding_Discriminal --
+ -- Find_Corresponding_Discriminal --
------------------------------------
- function Find_Corresponding_Discriminal (E : Entity_Id)
- return Entity_Id
+ function Find_Corresponding_Discriminal
+ (E : Entity_Id) return Entity_Id
is
R : Entity_Id;
return Empty;
end Find_Corresponding_Discriminal;
- function Replace_Discr_Ref (N : Node_Id) return Traverse_Result;
- -- Replace a reference to a discriminant of the original protected
- -- type by the local renaming declaration of the discriminant of
- -- the target object.
-
-----------------------
-- Replace_Discr_Ref --
-----------------------
- function Replace_Discr_Ref (N : Node_Id) return Traverse_Result is
+ function Replace_Discr_Ref (N : Node_Id) return Traverse_Result is
R : Entity_Id;
begin
if Is_Entity_Name (N)
- and then Present (Discriminal_Link (Entity (N)))
+ and then Present (Discriminal_Link (Entity (N)))
then
R := Find_Corresponding_Discriminal (Entity (N));
Rewrite (N, New_Occurrence_Of (R, Sloc (N)));
end if;
+
return OK;
end Replace_Discr_Ref;
procedure Replace_Discriminant_References is
new Traverse_Proc (Replace_Discr_Ref);
+ -- Start of processing for Replace_Discriminals_Of_Protected_Op
+
begin
Replace_Discriminant_References (Expr);
end Replace_Discriminals_Of_Protected_Op;
+ -- Start of processing for Expand_Pragma_Check
+
begin
-- Nothing to do if pragma is ignored
Set_Discrete_Choices (Assoc_Node, P_Discrete_Choice_List);
TF_Arrow;
Set_Expression (Assoc_Node, P_Expression);
+
+ if Ada_Version < Ada_2020 then
+ Error_Msg_SC ("Iterated component is an Ada 2020 extension");
+ Error_Msg_SC ("\compile with -gnatX");
+ end if;
+
return Assoc_Node;
end P_Iterated_Component_Association;
-- may have several choices, each one leading to a loop, so we create
-- this variable only once to prevent homonyms in this scope.
-- The expression has to be analyzed once the index variable is
- -- directly visible.
+ -- directly visible. Mark the variable as referenced to prevent
+ -- spurious warnings, given that subsequent uses of its name in the
+ -- expression will reference the internal (synonym) loop variable.
if No (Scope (Id)) then
Enter_Name (Id);
Set_Etype (Id, Index_Typ);
Set_Ekind (Id, E_Variable);
Set_Scope (Id, Ent);
+ Set_Referenced (Id);
end if;
Push_Scope (Ent);
Check_SPARK_05_Restriction
("unreachable code is not allowed", Error_Node);
else
- Error_Msg ("??unreachable code!", Sloc (Error_Node));
+ Error_Msg
+ ("??unreachable code!", Sloc (Error_Node), Error_Node);
end if;
end if;
----------------------
function Freeze_Type_Refs (Node : Node_Id) return Traverse_Result is
-
procedure Check_And_Freeze_Type (Typ : Entity_Id);
-- Check that Typ is fully declared and freeze it if so
if Has_Private_Component (Typ)
and then not Is_Private_Type (Typ)
then
- Error_Msg_NE
- ("\type& has private component", Node, Typ);
+ Error_Msg_NE ("\type& has private component", Node, Typ);
end if;
else
-- to complete the syntax checks. Certain pragmas are handled partially or
-- completely by the parser (see Par.Prag for further details).
-with Aspects; use Aspects;
-with Atree; use Atree;
-with Casing; use Casing;
-with Checks; use Checks;
-with Contracts; use Contracts;
-with Csets; use Csets;
-with Debug; use Debug;
-with Einfo; use Einfo;
-with Elists; use Elists;
-with Errout; use Errout;
-with Exp_Dist; use Exp_Dist;
-with Exp_Util; use Exp_Util;
-with Freeze; use Freeze;
-with Ghost; use Ghost;
-with Gnatvsn; use Gnatvsn;
-with Lib; use Lib;
-with Lib.Writ; use Lib.Writ;
-with Lib.Xref; use Lib.Xref;
-with Namet.Sp; use Namet.Sp;
-with Nlists; use Nlists;
-with Nmake; use Nmake;
-with Output; use Output;
-with Par_SCO; use Par_SCO;
-with Restrict; use Restrict;
-with Rident; use Rident;
-with Rtsfind; use Rtsfind;
-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_Ch12; use Sem_Ch12;
-with Sem_Ch13; use Sem_Ch13;
-with Sem_Disp; use Sem_Disp;
-with Sem_Dist; use Sem_Dist;
-with Sem_Elim; use Sem_Elim;
-with Sem_Eval; use Sem_Eval;
-with Sem_Intr; use Sem_Intr;
-with Sem_Mech; use Sem_Mech;
-with Sem_Res; use Sem_Res;
-with Sem_Type; use Sem_Type;
-with Sem_Util; use Sem_Util;
-with Sem_Warn; use Sem_Warn;
-with Stand; use Stand;
-with Sinfo; use Sinfo;
-with Sinfo.CN; use Sinfo.CN;
-with Sinput; use Sinput;
-with Stringt; use Stringt;
-with Stylesw; use Stylesw;
-with System.Case_Util;
+with Aspects; use Aspects;
+with Atree; use Atree;
+with Casing; use Casing;
+with Checks; use Checks;
+with Contracts; use Contracts;
+with Csets; use Csets;
+with Debug; use Debug;
+with Einfo; use Einfo;
+with Elists; use Elists;
+with Errout; use Errout;
+with Exp_Dist; use Exp_Dist;
+with Exp_Util; use Exp_Util;
+with Freeze; use Freeze;
+with Ghost; use Ghost;
+with Gnatvsn; use Gnatvsn;
+with Lib; use Lib;
+with Lib.Writ; use Lib.Writ;
+with Lib.Xref; use Lib.Xref;
+with Namet.Sp; use Namet.Sp;
+with Nlists; use Nlists;
+with Nmake; use Nmake;
+with Output; use Output;
+with Par_SCO; use Par_SCO;
+with Restrict; use Restrict;
+with Rident; use Rident;
+with Rtsfind; use Rtsfind;
+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_Ch12; use Sem_Ch12;
+with Sem_Ch13; use Sem_Ch13;
+with Sem_Disp; use Sem_Disp;
+with Sem_Dist; use Sem_Dist;
+with Sem_Elim; use Sem_Elim;
+with Sem_Eval; use Sem_Eval;
+with Sem_Intr; use Sem_Intr;
+with Sem_Mech; use Sem_Mech;
+with Sem_Res; use Sem_Res;
+with Sem_Type; use Sem_Type;
+with Sem_Util; use Sem_Util;
+with Sem_Warn; use Sem_Warn;
+with Stand; use Stand;
+with Sinfo; use Sinfo;
+with Sinfo.CN; use Sinfo.CN;
+with Sinput; use Sinput;
+with Stringt; use Stringt;
+with Stylesw; use Stylesw;
with Table;
-with Targparm; use Targparm;
-with Tbuild; use Tbuild;
+with Targparm; use Targparm;
+with Tbuild; use Tbuild;
with Ttypes;
-with Uintp; use Uintp;
-with Uname; use Uname;
-with Urealp; use Urealp;
-with Validsw; use Validsw;
-with Warnsw; use Warnsw;
+with Uintp; use Uintp;
+with Uname; use Uname;
+with Urealp; use Urealp;
+with Validsw; use Validsw;
+with Warnsw; use Warnsw;
+
+with System.Case_Util;
package body Sem_Prag is
Name_Increases)
then
declare
- Name : String :=
- Get_Name_String (Chars (Variant));
+ Name : String := Get_Name_String (Chars (Variant));
+
begin
-- It is a common mistake to write "Increasing" for
-- "Increases" or "Decreasing" for "Decreases". Recognize
with Debug; use Debug;
with Elists; use Elists;
with Errout; use Errout;
+with Erroutc; use Erroutc;
with Exp_Ch11; use Exp_Ch11;
with Exp_Disp; use Exp_Disp;
with Exp_Util; use Exp_Util;
-- becomes Requires_Transient_Scope and Old_Requires_Transient_Scope is
-- eliminated.
+ function Subprogram_Name (N : Node_Id) return String;
+ -- Return the fully qualified name of the enclosing subprogram for the
+ -- given node N.
+
------------------------------
-- Abstract_Interface_List --
------------------------------
end case;
end All_Composite_Constraints_Static;
+ ------------------------
+ -- Append_Entity_Name --
+ ------------------------
+
+ procedure Append_Entity_Name (Buf : in out Bounded_String; E : Entity_Id) is
+ Temp : Bounded_String;
+
+ procedure Inner (E : Entity_Id);
+ -- Inner recursive routine, keep outer routine nonrecursive to ease
+ -- debugging when we get strange results from this routine.
+
+ -----------
+ -- Inner --
+ -----------
+
+ procedure Inner (E : Entity_Id) is
+ begin
+ -- If entity has an internal name, skip by it, and print its scope.
+ -- Note that we strip a final R from the name before the test; this
+ -- is needed for some cases of instantiations.
+
+ declare
+ E_Name : Bounded_String;
+
+ begin
+ Append (E_Name, Chars (E));
+
+ if E_Name.Chars (E_Name.Length) = 'R' then
+ E_Name.Length := E_Name.Length - 1;
+ end if;
+
+ if Is_Internal_Name (E_Name) then
+ Inner (Scope (E));
+ return;
+ end if;
+ end;
+
+ -- Just print entity name if its scope is at the outer level
+
+ if Scope (E) = Standard_Standard then
+ null;
+
+ -- If scope comes from source, write scope and entity
+
+ elsif Comes_From_Source (Scope (E)) then
+ Append_Entity_Name (Temp, Scope (E));
+ Append (Temp, '.');
+
+ -- If in wrapper package skip past it
+
+ elsif Is_Wrapper_Package (Scope (E)) then
+ Append_Entity_Name (Temp, Scope (Scope (E)));
+ Append (Temp, '.');
+
+ -- Otherwise nothing to output (happens in unnamed block statements)
+
+ else
+ null;
+ end if;
+
+ -- Output the name
+
+ declare
+ E_Name : Bounded_String;
+
+ begin
+ Append_Unqualified_Decoded (E_Name, Chars (E));
+
+ -- Remove trailing upper-case letters from the name (useful for
+ -- dealing with some cases of internal names generated in the case
+ -- of references from within a generic).
+
+ while E_Name.Length > 1
+ and then E_Name.Chars (E_Name.Length) in 'A' .. 'Z'
+ loop
+ E_Name.Length := E_Name.Length - 1;
+ end loop;
+
+ -- Adjust casing appropriately (gets name from source if possible)
+
+ Adjust_Name_Case (E_Name, Sloc (E));
+ Append (Temp, E_Name);
+ end;
+ end Inner;
+
+ -- Start of processing for Append_Entity_Name
+
+ begin
+ Inner (E);
+ Append (Buf, Temp);
+ end Append_Entity_Name;
+
---------------------------------
-- Append_Inherited_Subprogram --
---------------------------------
-- Set_Rep_Info --
------------------
- procedure Set_Rep_Info (T1, T2 : Entity_Id) is
+ procedure Set_Rep_Info (T1 : Entity_Id; T2 : Entity_Id) is
begin
Set_Is_Atomic (T1, Is_Atomic (T2));
Set_Is_Independent (T1, Is_Independent (T2));
Set_Is_Volatile_Full_Access (T1, Is_Volatile_Full_Access (T2));
+
if Is_Base_Type (T1) then
Set_Is_Volatile (T1, Is_Volatile (T2));
end if;
end if;
end Subprogram_Access_Level;
+ ---------------------
+ -- Subprogram_Name --
+ ---------------------
+
+ function Subprogram_Name (N : Node_Id) return String is
+ Buf : Bounded_String;
+ Ent : Node_Id := N;
+
+ begin
+ while Present (Ent) loop
+ case Nkind (Ent) is
+ when N_Subprogram_Body =>
+ Ent := Defining_Unit_Name (Specification (Ent));
+ exit;
+
+ when N_Package_Body
+ | N_Package_Specification
+ | N_Subprogram_Specification
+ =>
+ Ent := Defining_Unit_Name (Ent);
+ exit;
+
+ when N_Protected_Body
+ | N_Protected_Type_Declaration
+ | N_Task_Body
+ =>
+ exit;
+
+ when others =>
+ null;
+ end case;
+
+ Ent := Parent (Ent);
+ end loop;
+
+ if No (Ent) then
+ return "unknown subprogram";
+ end if;
+
+ Append_Entity_Name (Buf, Ent);
+ return +Buf;
+ end Subprogram_Name;
+
-------------------------------
-- Support_Atomic_Primitives --
-------------------------------
end Yields_Universal_Type;
begin
- Errout.Current_Subprogram_Ptr := Current_Subprogram'Access;
+ Erroutc.Subprogram_Name_Ptr := Subprogram_Name'Access;
end Sem_Util;
-- irrelevant. Also called for array aggregates, but only named notation,
-- because those are the only dynamic cases.
+ procedure Append_Entity_Name (Buf : in out Bounded_String; E : Entity_Id);
+ -- Recursive procedure to construct string for qualified name of enclosing
+ -- program unit. The qualification stops at an enclosing scope has no
+ -- source name (block or loop). If entity is a subprogram instance, skip
+ -- enclosing wrapper package. The name is appended to Buf.
+
procedure Append_Inherited_Subprogram (S : Entity_Id);
-- If the parent of the operation is declared in the visible part of
-- the current scope, the inherited operation is visible even though the
-- (Referenced_As_LHS if Out_Param is False, Referenced_As_Out_Parameter
-- if Out_Param is True) is set True, and the other flag set False.
- procedure Set_Rep_Info (T1, T2 : Entity_Id);
+ procedure Set_Rep_Info (T1 : Entity_Id; T2 : Entity_Id);
pragma Inline (Set_Rep_Info);
-- Copies the Is_Atomic, Is_Independent and Is_Volatile_Full_Access flags
-- from sub(type) entity T2 to (sub)type entity T1, as well as Is_Volatile