mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 06:20:25 +08:00
errout.ads: Update comments for new handling of info: messages
2008-04-08 Robert Dewar <dewar@adacore.com> * errout.ads: Update comments for new handling of info: messages * erroutc.adb (Matches): New procedure (Warning_Specifically_Suppressed): Modified to handle multiple * chars (Is_Style_Or_Info_Msg): New name for Is_Style_Msg, now set for info messages as well as style messages. * erroutc.ads: Remove unneeded fields from Specific_Warning_Entry * sem_elab.adb (Supply_Bodies): Create actual bodies for stubbed subprograms. (Check_A_Call): Special "info: " warnings now have ? in the text (Elab_Warning): Use info message in static case From-SVN: r134024
This commit is contained in:
parent
68c3f02a68
commit
2dcf2584db
@ -6,7 +6,7 @@
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
|
||||
-- Copyright (C) 1992-2008, 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- --
|
||||
@ -275,14 +275,21 @@ package Errout is
|
||||
-- Insertion character ? (Question: warning message)
|
||||
-- The character ? appearing anywhere in a message makes the message
|
||||
-- warning instead of a normal error message, and the text of the
|
||||
-- message will be preceded by "Warning:" instead of "Error:" in the
|
||||
-- normal case. The handling of warnings if further controlled by the
|
||||
-- Warning_Mode option (-w switch), see package Opt for further
|
||||
-- details, and also by the current setting from pragma Warnings. This
|
||||
-- pragma applies only to warnings issued from the semantic phase (not
|
||||
-- the parser), but currently all relevant warnings are posted by the
|
||||
-- semantic phase anyway. Messages starting with (style) are also
|
||||
-- treated as warning messages.
|
||||
-- message will be preceded by "warning:" in the normal case. The
|
||||
-- handling of warnings if further controlled by the Warning_Mode
|
||||
-- option (-w switch), see package Opt for further details, and also by
|
||||
-- the current setting from pragma Warnings. This pragma applies only
|
||||
-- to warnings issued from the semantic phase (not the parser), but
|
||||
-- currently all relevant warnings are posted by the semantic phase
|
||||
-- anyway. Messages starting with (style) are also treated as warning
|
||||
-- messages.
|
||||
--
|
||||
-- Note: when a warning message is output, the text of the message is
|
||||
-- preceded by "warning: " in the normal case. An exception to this
|
||||
-- rule occurs when the text of the message starts with "info: " in
|
||||
-- which case this string is not prepended. This allows callers to
|
||||
-- label certain warnings as informational messages, rather than as
|
||||
-- warning messages requiring some action.
|
||||
--
|
||||
-- Note: the presence of ? is ignored in continuation messages (i.e.
|
||||
-- messages starting with the \ insertion character). The warning
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
|
||||
-- Copyright (C) 1992-2008, 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- --
|
||||
@ -117,6 +117,7 @@ package body Erroutc is
|
||||
|
||||
if Errors.Table (D).Warn or Errors.Table (D).Style then
|
||||
Warnings_Detected := Warnings_Detected - 1;
|
||||
|
||||
else
|
||||
Total_Errors_Detected := Total_Errors_Detected - 1;
|
||||
|
||||
@ -441,6 +442,12 @@ package body Erroutc is
|
||||
Length : Nat;
|
||||
-- Maximum total length of lines
|
||||
|
||||
Txt : constant String_Ptr := Errors.Table (E).Text;
|
||||
Len : constant Natural := Txt'Length;
|
||||
Ptr : Natural;
|
||||
Split : Natural;
|
||||
Start : Natural;
|
||||
|
||||
begin
|
||||
if Error_Msg_Line_Length = 0 then
|
||||
Length := Nat'Last;
|
||||
@ -450,13 +457,21 @@ package body Erroutc is
|
||||
|
||||
Max := Integer (Length - Column + 1);
|
||||
|
||||
-- For warning message, add "warning: " unless msg starts with "info: "
|
||||
|
||||
if Errors.Table (E).Warn then
|
||||
Write_Str ("warning: ");
|
||||
Max := Max - 9;
|
||||
if Len < 6 or else Txt (Txt'First .. Txt'First + 5) /= "info: " then
|
||||
Write_Str ("warning: ");
|
||||
Max := Max - 9;
|
||||
end if;
|
||||
|
||||
-- No prefix needed for style message, since "(style)" is there already
|
||||
|
||||
elsif Errors.Table (E).Style then
|
||||
null;
|
||||
|
||||
-- All other cases, add "error: "
|
||||
|
||||
elsif Opt.Unique_Error_Tag then
|
||||
Write_Str ("error: ");
|
||||
Max := Max - 7;
|
||||
@ -464,74 +479,65 @@ package body Erroutc is
|
||||
|
||||
-- Here we have to split the message up into multiple lines
|
||||
|
||||
declare
|
||||
Txt : constant String_Ptr := Errors.Table (E).Text;
|
||||
Len : constant Natural := Txt'Length;
|
||||
Ptr : Natural;
|
||||
Split : Natural;
|
||||
Start : Natural;
|
||||
Ptr := 1;
|
||||
loop
|
||||
-- Make sure we do not have ludicrously small line
|
||||
|
||||
begin
|
||||
Ptr := 1;
|
||||
loop
|
||||
-- Make sure we do not have ludicrously small line
|
||||
Max := Integer'Max (Max, 20);
|
||||
|
||||
Max := Integer'Max (Max, 20);
|
||||
-- If remaining text fits, output it respecting LF and we are done
|
||||
|
||||
-- If remaining text fits, output it respecting LF and we are done
|
||||
if Len - Ptr < Max then
|
||||
for J in Ptr .. Len loop
|
||||
if Txt (J) = ASCII.LF then
|
||||
Write_Eol;
|
||||
Write_Spaces (Offs);
|
||||
else
|
||||
Write_Char (Txt (J));
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if Len - Ptr < Max then
|
||||
for J in Ptr .. Len loop
|
||||
if Txt (J) = ASCII.LF then
|
||||
Write_Eol;
|
||||
Write_Spaces (Offs);
|
||||
else
|
||||
Write_Char (Txt (J));
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return;
|
||||
return;
|
||||
|
||||
-- Line does not fit
|
||||
|
||||
else
|
||||
Start := Ptr;
|
||||
else
|
||||
Start := Ptr;
|
||||
|
||||
-- First scan forward looing for a hard end of line
|
||||
-- First scan forward looing for a hard end of line
|
||||
|
||||
for Scan in Ptr .. Ptr + Max - 1 loop
|
||||
if Txt (Scan) = ASCII.LF then
|
||||
Split := Scan - 1;
|
||||
Ptr := Scan + 1;
|
||||
goto Continue;
|
||||
end if;
|
||||
end loop;
|
||||
for Scan in Ptr .. Ptr + Max - 1 loop
|
||||
if Txt (Scan) = ASCII.LF then
|
||||
Split := Scan - 1;
|
||||
Ptr := Scan + 1;
|
||||
goto Continue;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
-- Otherwise scan backwards looking for a space
|
||||
-- Otherwise scan backwards looking for a space
|
||||
|
||||
for Scan in reverse Ptr .. Ptr + Max - 1 loop
|
||||
if Txt (Scan) = ' ' then
|
||||
Split := Scan - 1;
|
||||
Ptr := Scan + 1;
|
||||
goto Continue;
|
||||
end if;
|
||||
end loop;
|
||||
for Scan in reverse Ptr .. Ptr + Max - 1 loop
|
||||
if Txt (Scan) = ' ' then
|
||||
Split := Scan - 1;
|
||||
Ptr := Scan + 1;
|
||||
goto Continue;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
-- If we fall through, no space, so split line arbitrarily
|
||||
-- If we fall through, no space, so split line arbitrarily
|
||||
|
||||
Split := Ptr + Max - 1;
|
||||
Ptr := Split + 1;
|
||||
end if;
|
||||
Split := Ptr + Max - 1;
|
||||
Ptr := Split + 1;
|
||||
end if;
|
||||
|
||||
<<Continue>>
|
||||
if Start <= Split then
|
||||
Write_Line (Txt (Start .. Split));
|
||||
Write_Spaces (Offs);
|
||||
end if;
|
||||
if Start <= Split then
|
||||
Write_Line (Txt (Start .. Split));
|
||||
Write_Spaces (Offs);
|
||||
end if;
|
||||
|
||||
Max := Integer (Length - Column + 1);
|
||||
end loop;
|
||||
end;
|
||||
Max := Integer (Length - Column + 1);
|
||||
end loop;
|
||||
end Output_Msg_Text;
|
||||
|
||||
--------------------
|
||||
@ -557,6 +563,7 @@ package body Erroutc is
|
||||
then
|
||||
if Errors.Table (E).Warn or Errors.Table (E).Style then
|
||||
Warnings_Detected := Warnings_Detected - 1;
|
||||
|
||||
else
|
||||
Total_Errors_Detected := Total_Errors_Detected - 1;
|
||||
|
||||
@ -1052,40 +1059,13 @@ package body Erroutc is
|
||||
Msg : String;
|
||||
Config : Boolean)
|
||||
is
|
||||
pragma Assert (Msg'First = 1);
|
||||
|
||||
Pattern : String := Msg;
|
||||
Patlen : Natural := Msg'Length;
|
||||
|
||||
Star_Start : Boolean;
|
||||
Star_End : Boolean;
|
||||
|
||||
begin
|
||||
if Pattern (1) = '*' then
|
||||
Star_Start := True;
|
||||
Pattern (1 .. Patlen - 1) := Pattern (2 .. Patlen);
|
||||
Patlen := Patlen - 1;
|
||||
else
|
||||
Star_Start := False;
|
||||
end if;
|
||||
|
||||
if Pattern (Patlen) = '*' then
|
||||
Star_End := True;
|
||||
Patlen := Patlen - 1;
|
||||
else
|
||||
Star_End := False;
|
||||
end if;
|
||||
|
||||
Specific_Warnings.Append
|
||||
((Start => Loc,
|
||||
Msg => new String'(Msg),
|
||||
Pattern => new String'(Pattern (1 .. Patlen)),
|
||||
Patlen => Patlen,
|
||||
Stop => Source_Last (Current_Source_File),
|
||||
Open => True,
|
||||
Used => False,
|
||||
Star_Start => Star_Start,
|
||||
Star_End => Star_End,
|
||||
Config => Config));
|
||||
end Set_Specific_Warning_Off;
|
||||
|
||||
@ -1200,8 +1180,7 @@ package body Erroutc is
|
||||
Is_Warning_Msg := False;
|
||||
|
||||
Is_Style_Msg :=
|
||||
(Msg'Length > 7
|
||||
and then Msg (Msg'First .. Msg'First + 6) = "(style)");
|
||||
(Msg'Length > 7 and then Msg (Msg'First .. Msg'First + 6) = "(style)");
|
||||
|
||||
if Is_Style_Msg then
|
||||
Is_Serious_Error := False;
|
||||
@ -1225,7 +1204,7 @@ package body Erroutc is
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if Is_Warning_Msg or else Is_Style_Msg then
|
||||
if Is_Warning_Msg or Is_Style_Msg then
|
||||
Is_Serious_Error := False;
|
||||
end if;
|
||||
end Test_Style_Warning_Serious_Msg;
|
||||
@ -1262,22 +1241,73 @@ package body Erroutc is
|
||||
(Loc : Source_Ptr;
|
||||
Msg : String_Ptr) return Boolean
|
||||
is
|
||||
pragma Assert (Msg'First = 1);
|
||||
function Matches (S : String; P : String) return Boolean;
|
||||
-- Returns true if the String S patches the pattern P, which can contain
|
||||
-- wild card chars (*). The entire pattern must match the entire string.
|
||||
|
||||
Msglen : constant Natural := Msg'Length;
|
||||
Patlen : Natural;
|
||||
-- Length of message
|
||||
-------------
|
||||
-- Matches --
|
||||
-------------
|
||||
|
||||
Pattern : String_Ptr;
|
||||
-- Pattern itself, excluding initial and final *
|
||||
function Matches (S : String; P : String) return Boolean is
|
||||
Slast : constant Natural := S'Last;
|
||||
PLast : constant Natural := P'Last;
|
||||
|
||||
Star_Start : Boolean;
|
||||
Star_End : Boolean;
|
||||
-- Indications of * at start and end of original pattern
|
||||
SPtr : Natural := S'First;
|
||||
PPtr : Natural := P'First;
|
||||
|
||||
Msgp : Natural;
|
||||
Patp : Natural;
|
||||
-- Scan pointers for message and pattern
|
||||
begin
|
||||
-- Loop advancing through characters of string and pattern
|
||||
|
||||
SPtr := S'First;
|
||||
PPtr := P'First;
|
||||
loop
|
||||
-- Return True if pattern is a single asterisk
|
||||
|
||||
if PPtr = PLast and then P (PPtr) = '*' then
|
||||
return True;
|
||||
|
||||
-- Return True if both pattern and string exhausted
|
||||
|
||||
elsif PPtr > PLast and then SPtr > Slast then
|
||||
return True;
|
||||
|
||||
-- Return False, if one exhausted and not the other
|
||||
|
||||
elsif PPtr > PLast or else SPtr > Slast then
|
||||
return False;
|
||||
|
||||
-- Case where pattern starts with asterisk
|
||||
|
||||
elsif P (PPtr) = '*' then
|
||||
|
||||
-- Try all possible starting positions in S for match with
|
||||
-- the remaining characters of the pattern. This is the
|
||||
-- recursive call that implements the scanner backup.
|
||||
|
||||
for J in SPtr .. Slast loop
|
||||
if Matches (S (J .. Slast), P (PPtr + 1 .. PLast)) then
|
||||
return True;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return False;
|
||||
|
||||
-- Dealt with end of string and *, advance if we have a match
|
||||
|
||||
elsif S (SPtr) = P (PPtr) then
|
||||
SPtr := SPtr + 1;
|
||||
PPtr := PPtr + 1;
|
||||
|
||||
-- If first characters do not match, that's decisive
|
||||
|
||||
else
|
||||
return False;
|
||||
end if;
|
||||
end loop;
|
||||
end Matches;
|
||||
|
||||
-- Start of processing for Warning_Specifically_Suppressed
|
||||
|
||||
begin
|
||||
-- Loop through specific warning suppression entries
|
||||
@ -1293,79 +1323,10 @@ package body Erroutc is
|
||||
if SWE.Config
|
||||
or else (SWE.Start <= Loc and then Loc <= SWE.Stop)
|
||||
then
|
||||
-- Check if message matches, dealing with * patterns
|
||||
|
||||
Patlen := SWE.Patlen;
|
||||
Pattern := SWE.Pattern;
|
||||
Star_Start := SWE.Star_Start;
|
||||
Star_End := SWE.Star_End;
|
||||
|
||||
-- Loop through possible starting positions in Msg
|
||||
|
||||
Outer : for M in 1 .. 1 + (Msglen - Patlen) loop
|
||||
|
||||
-- See if pattern matches string starting at Msg (J)
|
||||
|
||||
Msgp := M;
|
||||
Patp := 1;
|
||||
Inner : loop
|
||||
|
||||
-- If pattern exhausted, then match if we are at end
|
||||
-- of message, or if pattern ended with an asterisk,
|
||||
-- otherwise match failure at this position.
|
||||
|
||||
if Patp > Patlen then
|
||||
if Msgp > Msglen or else Star_End then
|
||||
SWE.Used := True;
|
||||
return True;
|
||||
else
|
||||
exit Inner;
|
||||
end if;
|
||||
|
||||
-- Otherwise if message exhausted (and we still have
|
||||
-- pattern characters left), then match failure here.
|
||||
|
||||
elsif Msgp > Msglen then
|
||||
exit Inner;
|
||||
end if;
|
||||
|
||||
-- Here we have pattern and message characters left
|
||||
|
||||
-- Handle "*" pattern match
|
||||
|
||||
if Patp < Patlen - 1 and then
|
||||
Pattern (Patp .. Patp + 2) = """*"""
|
||||
then
|
||||
Patp := Patp + 3;
|
||||
|
||||
-- Must have " and at least three chars in msg or we
|
||||
-- have no match at this position.
|
||||
|
||||
exit Inner when Msg (Msgp) /= '"';
|
||||
Msgp := Msgp + 1;
|
||||
|
||||
-- Scan out " string " in message
|
||||
|
||||
Scan : loop
|
||||
exit Inner when Msgp = Msglen;
|
||||
Msgp := Msgp + 1;
|
||||
exit Scan when Msg (Msgp - 1) = '"';
|
||||
end loop Scan;
|
||||
|
||||
-- If not "*" case, just compare character
|
||||
|
||||
else
|
||||
exit Inner when Pattern (Patp) /= Msg (Msgp);
|
||||
Patp := Patp + 1;
|
||||
Msgp := Msgp + 1;
|
||||
end if;
|
||||
end loop Inner;
|
||||
|
||||
-- Advance to next position if star at end of original
|
||||
-- pattern, otherwise no more match attempts are possible
|
||||
|
||||
exit Outer when not Star_Start;
|
||||
end loop Outer;
|
||||
if Matches (Msg.all, SWE.Msg.all) then
|
||||
SWE.Used := True;
|
||||
return True;
|
||||
end if;
|
||||
end if;
|
||||
end;
|
||||
end loop;
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
|
||||
-- Copyright (C) 1992-2008, 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- --
|
||||
@ -52,6 +52,7 @@ package Erroutc is
|
||||
|
||||
Is_Style_Msg : Boolean := False;
|
||||
-- Set True to indicate if the current message is a style message
|
||||
-- (i.e. a message whose text starts with the cahracters "(style)").
|
||||
|
||||
Is_Serious_Error : Boolean := False;
|
||||
-- Set by Set_Msg_Text to indicate if current message is serious error
|
||||
@ -267,25 +268,12 @@ package Erroutc is
|
||||
Msg : String_Ptr;
|
||||
-- Message from pragma Warnings (Off, string)
|
||||
|
||||
Pattern : String_Ptr;
|
||||
-- Same as Msg, excluding initial and final asterisks if present. The
|
||||
-- lower bound of this string is always one.
|
||||
|
||||
Patlen : Natural;
|
||||
-- Length of pattern string (excluding initial/final asterisks)
|
||||
|
||||
Open : Boolean;
|
||||
-- Set to True if OFF has been encountered with no matching ON
|
||||
|
||||
Used : Boolean;
|
||||
-- Set to True if entry has been used to suppress a warning
|
||||
|
||||
Star_Start : Boolean;
|
||||
-- True if given pattern had * at start
|
||||
|
||||
Star_End : Boolean;
|
||||
-- True if given pattern had * at end
|
||||
|
||||
Config : Boolean;
|
||||
-- True if pragma is configuration pragma (in which case no matching
|
||||
-- Off pragma is required, and it is not required that a specific
|
||||
@ -482,12 +470,12 @@ package Erroutc is
|
||||
|
||||
procedure Test_Style_Warning_Serious_Msg (Msg : String);
|
||||
-- Sets Is_Warning_Msg true if Msg is a warning message (contains a
|
||||
-- question mark character), and False otherwise. Sets Is_Style_Msg
|
||||
-- true if Msg is a style message (starts with "(style)"). Sets
|
||||
-- Is_Serious_Error True unless the message is a warning or style
|
||||
-- message or contains the character | indicating a non-serious
|
||||
-- error message. Note that the call has no effect for continuation
|
||||
-- messages (those whose first character is \).
|
||||
-- question mark character), and False otherwise. Is_Style_Msg is set true
|
||||
-- if Msg is a style message (starts with "(style)". Sets Is_Serious_Error
|
||||
-- True unless the message is a warning or style/info message or contains
|
||||
-- the character | indicating a non-serious error message. Note that the
|
||||
-- call has no effect for continuation messages (those whose first
|
||||
-- character is '\').
|
||||
|
||||
function Warnings_Suppressed (Loc : Source_Ptr) return Boolean;
|
||||
-- Determines if given location is covered by a warnings off suppression
|
||||
|
@ -58,11 +58,11 @@ with Uname; use Uname;
|
||||
|
||||
package body Sem_Elab is
|
||||
|
||||
-- The following table records the recursive call chain for output
|
||||
-- in the Output routine. Each entry records the call node and the
|
||||
-- entity of the called routine. The number of entries in the table
|
||||
-- (i.e. the value of Elab_Call.Last) indicates the current depth
|
||||
-- of recursion and is used to identify the outer level.
|
||||
-- The following table records the recursive call chain for output in the
|
||||
-- Output routine. Each entry records the call node and the entity of the
|
||||
-- called routine. The number of entries in the table (i.e. the value of
|
||||
-- Elab_Call.Last) indicates the current depth of recursion and is used to
|
||||
-- identify the outer level.
|
||||
|
||||
type Elab_Call_Entry is record
|
||||
Cloc : Source_Ptr;
|
||||
@ -77,10 +77,10 @@ package body Sem_Elab is
|
||||
Table_Increment => 100,
|
||||
Table_Name => "Elab_Call");
|
||||
|
||||
-- This table is initialized at the start of each outer level call.
|
||||
-- It holds the entities for all subprograms that have been examined
|
||||
-- for this particular outer level call, and is used to prevent both
|
||||
-- infinite recursion, and useless reanalysis of bodies already seen
|
||||
-- This table is initialized at the start of each outer level call. It
|
||||
-- holds the entities for all subprograms that have been examined for this
|
||||
-- particular outer level call, and is used to prevent both infinite
|
||||
-- recursion, and useless reanalysis of bodies already seen
|
||||
|
||||
package Elab_Visited is new Table.Table (
|
||||
Table_Component_Type => Entity_Id,
|
||||
@ -127,9 +127,8 @@ package body Sem_Elab is
|
||||
Table_Name => "Delay_Check");
|
||||
|
||||
C_Scope : Entity_Id;
|
||||
-- Top level scope of current scope. We need to compute this only
|
||||
-- once at the outer level, i.e. for a call to Check_Elab_Call from
|
||||
-- outside this unit.
|
||||
-- Top level scope of current scope. Compute this only once at the outer
|
||||
-- level, i.e. for a call to Check_Elab_Call from outside this unit.
|
||||
|
||||
Outer_Level_Sloc : Source_Ptr;
|
||||
-- Save Sloc value for outer level call node for comparisons of source
|
||||
@ -149,9 +148,9 @@ package body Sem_Elab is
|
||||
|
||||
Delaying_Elab_Checks : Boolean := True;
|
||||
-- This is set True till the compilation is complete, including the
|
||||
-- insertion of all instance bodies. Then when Check_Elab_Calls is
|
||||
-- called, the delay table is used to make the delayed calls and
|
||||
-- this flag is reset to False, so that the calls are processed
|
||||
-- insertion of all instance bodies. Then when Check_Elab_Calls is called,
|
||||
-- the delay table is used to make the delayed calls and this flag is reset
|
||||
-- to False, so that the calls are processed
|
||||
|
||||
-----------------------
|
||||
-- Local Subprograms --
|
||||
@ -177,16 +176,15 @@ package body Sem_Elab is
|
||||
Outer_Scope : Entity_Id;
|
||||
Inter_Unit_Only : Boolean;
|
||||
Generate_Warnings : Boolean := True);
|
||||
-- This is the internal recursive routine that is called to check for
|
||||
-- a possible elaboration error. The argument N is a subprogram call
|
||||
-- or generic instantiation to be checked, and E is the entity of
|
||||
-- the called subprogram, or instantiated generic unit. The flag
|
||||
-- Outer_Scope is the outer level scope for the original call.
|
||||
-- Inter_Unit_Only is set if the call is only to be checked in the
|
||||
-- case where it is to another unit (and skipped if within a unit).
|
||||
-- Generate_Warnings is set to False to suppress warning messages
|
||||
-- about missing pragma Elaborate_All's. These messages are not
|
||||
-- wanted for inner calls in the dynamic model.
|
||||
-- This is the internal recursive routine that is called to check for a
|
||||
-- possible elaboration error. The argument N is a subprogram call or
|
||||
-- generic instantiation to be checked, and E is the entity of the called
|
||||
-- subprogram, or instantiated generic unit. The flag Outer_Scope is the
|
||||
-- outer level scope for the original call. Inter_Unit_Only is set if the
|
||||
-- call is only to be checked in the case where it is to another unit (and
|
||||
-- skipped if within a unit). Generate_Warnings is set to False to suppress
|
||||
-- warning messages about missing pragma Elaborate_All's. These messages
|
||||
-- are not wanted for inner calls in the dynamic model.
|
||||
|
||||
procedure Check_Bad_Instantiation (N : Node_Id);
|
||||
-- N is a node for an instantiation (if called with any other node kind,
|
||||
@ -207,14 +205,14 @@ package body Sem_Elab is
|
||||
E : Entity_Id;
|
||||
Outer_Scope : Entity_Id;
|
||||
Orig_Ent : Entity_Id);
|
||||
-- N is a function call or procedure statement call node and E is
|
||||
-- the entity of the called function, which is within the current
|
||||
-- compilation unit (where subunits count as part of the parent).
|
||||
-- This call checks if this call, or any call within any accessed
|
||||
-- body could cause an ABE, and if so, outputs a warning. Orig_Ent
|
||||
-- differs from E only in the case of renamings, and points to the
|
||||
-- original name of the entity. This is used for error messages.
|
||||
-- Outer_Scope is the outer level scope for the original call.
|
||||
-- N is a function call or procedure statement call node and E is the
|
||||
-- entity of the called function, which is within the current compilation
|
||||
-- unit (where subunits count as part of the parent). This call checks if
|
||||
-- this call, or any call within any accessed body could cause an ABE, and
|
||||
-- if so, outputs a warning. Orig_Ent differs from E only in the case of
|
||||
-- renamings, and points to the original name of the entity. This is used
|
||||
-- for error messages. Outer_Scope is the outer level scope for the
|
||||
-- original call.
|
||||
|
||||
procedure Check_Internal_Call_Continue
|
||||
(N : Node_Id;
|
||||
@ -224,10 +222,10 @@ package body Sem_Elab is
|
||||
-- The processing for Check_Internal_Call is divided up into two phases,
|
||||
-- and this represents the second phase. The second phase is delayed if
|
||||
-- Delaying_Elab_Calls is set to True. In this delayed case, the first
|
||||
-- phase makes an entry in the Delay_Check table, which is processed
|
||||
-- when Check_Elab_Calls is called. N, E and Orig_Ent are as for the call
|
||||
-- to Check_Internal_Call. Outer_Scope is the outer level scope for
|
||||
-- the original call.
|
||||
-- phase makes an entry in the Delay_Check table, which is processed when
|
||||
-- Check_Elab_Calls is called. N, E and Orig_Ent are as for the call to
|
||||
-- Check_Internal_Call. Outer_Scope is the outer level scope for the
|
||||
-- original call.
|
||||
|
||||
procedure Set_Elaboration_Constraint
|
||||
(Call : Node_Id;
|
||||
@ -268,16 +266,16 @@ package body Sem_Elab is
|
||||
-- inevitable, given the optional body semantics of Ada).
|
||||
|
||||
procedure Insert_Elab_Check (N : Node_Id; C : Node_Id := Empty);
|
||||
-- Given code for an elaboration check (or unconditional raise if
|
||||
-- the check is not needed), inserts the code in the appropriate
|
||||
-- place. N is the call or instantiation node for which the check
|
||||
-- code is required. C is the test whose failure triggers the raise.
|
||||
-- Given code for an elaboration check (or unconditional raise if the check
|
||||
-- is not needed), inserts the code in the appropriate place. N is the call
|
||||
-- or instantiation node for which the check code is required. C is the
|
||||
-- test whose failure triggers the raise.
|
||||
|
||||
procedure Output_Calls (N : Node_Id);
|
||||
-- Outputs chain of calls stored in the Elab_Call table. The caller
|
||||
-- has already generated the main warning message, so the warnings
|
||||
-- generated are all continuation messages. The argument is the
|
||||
-- call node at which the messages are to be placed.
|
||||
-- Outputs chain of calls stored in the Elab_Call table. The caller has
|
||||
-- already generated the main warning message, so the warnings generated
|
||||
-- are all continuation messages. The argument is the call node at which
|
||||
-- the messages are to be placed.
|
||||
|
||||
function Same_Elaboration_Scope (Scop1, Scop2 : Entity_Id) return Boolean;
|
||||
-- Given two scopes, determine whether they are the same scope from an
|
||||
@ -288,17 +286,16 @@ package body Sem_Elab is
|
||||
-- to be the enclosing compilation unit of this scope.
|
||||
|
||||
function Spec_Entity (E : Entity_Id) return Entity_Id;
|
||||
-- Given a compilation unit entity, if it is a spec entity, it is
|
||||
-- returned unchanged. If it is a body entity, then the spec for
|
||||
-- the corresponding spec is returned
|
||||
-- Given a compilation unit entity, if it is a spec entity, it is returned
|
||||
-- unchanged. If it is a body entity, then the spec for the corresponding
|
||||
-- spec is returned
|
||||
|
||||
procedure Supply_Bodies (N : Node_Id);
|
||||
-- Given a node, N, that is either a subprogram declaration or a package
|
||||
-- declaration, this procedure supplies dummy bodies for the subprogram
|
||||
-- or for all subprograms in the package. If the given node is not one
|
||||
-- of these two possibilities, then Supply_Bodies does nothing. The
|
||||
-- dummy body is supplied by setting the subprogram to be Imported with
|
||||
-- convention Stubbed.
|
||||
-- dummy body contains a single Raise statement.
|
||||
|
||||
procedure Supply_Bodies (L : List_Id);
|
||||
-- Calls Supply_Bodies for all elements of the given list L
|
||||
@ -480,11 +477,10 @@ package body Sem_Elab is
|
||||
Decl : Node_Id;
|
||||
|
||||
E_Scope : Entity_Id;
|
||||
-- Top level scope of entity for called subprogram. This
|
||||
-- value includes following renamings and derivations, so
|
||||
-- this scope can be in a non-visible unit. This is the
|
||||
-- scope that is to be investigated to see whether an
|
||||
-- elaboration check is required.
|
||||
-- Top level scope of entity for called subprogram. This value includes
|
||||
-- following renamings and derivations, so this scope can be in a
|
||||
-- non-visible unit. This is the scope that is to be investigated to
|
||||
-- see whether an elaboration check is required.
|
||||
|
||||
W_Scope : Entity_Id;
|
||||
-- Top level scope of directly called entity for subprogram. This
|
||||
@ -531,8 +527,8 @@ package body Sem_Elab is
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Go to parent for derived subprogram, or to original subprogram
|
||||
-- in the case of a renaming (Alias covers both these cases)
|
||||
-- Go to parent for derived subprogram, or to original subprogram in the
|
||||
-- case of a renaming (Alias covers both these cases).
|
||||
|
||||
Ent := E;
|
||||
loop
|
||||
@ -646,16 +642,16 @@ package body Sem_Elab is
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Nothing to do for a generic instance, because in this case
|
||||
-- the checking was at the point of instantiation of the generic
|
||||
-- However, this shortcut is only applicable in static mode.
|
||||
-- Nothing to do for a generic instance, because in this case the
|
||||
-- checking was at the point of instantiation of the generic However,
|
||||
-- this shortcut is only applicable in static mode.
|
||||
|
||||
if Is_Generic_Instance (Ent) and not Dynamic_Elaboration_Checks then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Nothing to do if subprogram with no separate spec. However,
|
||||
-- a call to Deep_Initialize may result in a call to a user-defined
|
||||
-- Nothing to do if subprogram with no separate spec. However, a
|
||||
-- call to Deep_Initialize may result in a call to a user-defined
|
||||
-- Initialize procedure, which imposes a body dependency. This
|
||||
-- happens only if the type is controlled and the Initialize
|
||||
-- procedure is not inherited.
|
||||
@ -762,8 +758,8 @@ package body Sem_Elab is
|
||||
then
|
||||
E_Scope := Spec_Entity (Cunit_Entity (Unit_Caller));
|
||||
|
||||
-- If we don't get a spec entity, just ignore call. Not
|
||||
-- quite clear why this check is necessary.
|
||||
-- If we don't get a spec entity, just ignore call. Not quite
|
||||
-- clear why this check is necessary. ???
|
||||
|
||||
if No (E_Scope) then
|
||||
return;
|
||||
@ -775,16 +771,15 @@ package body Sem_Elab is
|
||||
E_Scope := Scope (E_Scope);
|
||||
end loop;
|
||||
|
||||
-- For the case N is not an instance, or a call within instance
|
||||
-- We recompute E_Scope for the error message, since we
|
||||
-- do NOT want to go to the unit which has the ultimate
|
||||
-- declaration in the case of renaming and derivation and
|
||||
-- we also want to go to the generic unit in the case of
|
||||
-- an instance, and no further.
|
||||
-- For the case N is not an instance, or a call within instance, we
|
||||
-- recompute E_Scope for the error message, since we do NOT want to
|
||||
-- go to the unit which has the ultimate declaration in the case of
|
||||
-- renaming and derivation and we also want to go to the generic unit
|
||||
-- in the case of an instance, and no further.
|
||||
|
||||
else
|
||||
-- Loop to carefully follow renamings and derivations
|
||||
-- one step outside the current unit, but not further.
|
||||
-- Loop to carefully follow renamings and derivations one step
|
||||
-- outside the current unit, but not further.
|
||||
|
||||
if not Inst_Case
|
||||
and then Present (Alias (Ent))
|
||||
@ -879,7 +874,7 @@ package body Sem_Elab is
|
||||
if Inst_Case then
|
||||
Elab_Warning
|
||||
("instantiation of& may raise Program_Error?",
|
||||
"instantiation of& during elaboration?", Ent);
|
||||
"info: instantiation of& during elaboration?", Ent);
|
||||
|
||||
else
|
||||
if Nkind (Name (N)) in N_Has_Entity
|
||||
@ -888,13 +883,13 @@ package body Sem_Elab is
|
||||
then
|
||||
Elab_Warning
|
||||
("implicit call to & may raise Program_Error?",
|
||||
"implicit call to & during elaboration?",
|
||||
"info: implicit call to & during elaboration?",
|
||||
Ent);
|
||||
|
||||
else
|
||||
Elab_Warning
|
||||
("call to & may raise Program_Error?",
|
||||
"call to & during elaboration?",
|
||||
"info: call to & during elaboration?",
|
||||
Ent);
|
||||
end if;
|
||||
end if;
|
||||
@ -904,12 +899,12 @@ package body Sem_Elab is
|
||||
if Nkind (N) in N_Subprogram_Instantiation then
|
||||
Elab_Warning
|
||||
("\missing pragma Elaborate for&?",
|
||||
"\implicit pragma Elaborate for& generated?",
|
||||
"\info: implicit pragma Elaborate for& generated?",
|
||||
W_Scope);
|
||||
else
|
||||
Elab_Warning
|
||||
("\missing pragma Elaborate_All for&?",
|
||||
"\implicit pragma Elaborate_All for & generated?",
|
||||
"\info: implicit pragma Elaborate_All for & generated?",
|
||||
W_Scope);
|
||||
end if;
|
||||
end Generate_Elab_Warnings;
|
||||
@ -936,8 +931,8 @@ package body Sem_Elab is
|
||||
-- Runtime elaboration check required. Generate check of the
|
||||
-- elaboration Boolean for the unit containing the entity.
|
||||
|
||||
-- Note that for this case, we do check the real unit (the
|
||||
-- one from following renamings, since that is the issue!)
|
||||
-- Note that for this case, we do check the real unit (the one
|
||||
-- from following renamings, since that is the issue!)
|
||||
|
||||
-- Could this possibly miss a useless but required PE???
|
||||
|
||||
@ -952,10 +947,10 @@ package body Sem_Elab is
|
||||
-- Case of static elaboration model
|
||||
|
||||
else
|
||||
-- Do not do anything if elaboration checks suppressed. Note
|
||||
-- that we check Ent here, not E, since we want the real entity
|
||||
-- for the body to see if checks are suppressed for it, not the
|
||||
-- dummy entry for renamings or derivations.
|
||||
-- Do not do anything if elaboration checks suppressed. Note that
|
||||
-- we check Ent here, not E, since we want the real entity for the
|
||||
-- body to see if checks are suppressed for it, not the dummy
|
||||
-- entry for renamings or derivations.
|
||||
|
||||
if Elaboration_Checks_Suppressed (Ent)
|
||||
or else Elaboration_Checks_Suppressed (E_Scope)
|
||||
@ -1111,7 +1106,7 @@ package body Sem_Elab is
|
||||
function Get_Called_Ent return Entity_Id;
|
||||
-- Retrieve called entity. If this is a call to a protected subprogram,
|
||||
-- entity is a selected component. The callable entity may be absent,
|
||||
-- in which case there is no check to perform. This happens with
|
||||
-- in which case there is no check to perform. This happens with
|
||||
-- non-analyzed calls in nested generics.
|
||||
|
||||
--------------------
|
||||
@ -1201,8 +1196,8 @@ package body Sem_Elab is
|
||||
-- is at the time of the actual call (statically speaking) that we must
|
||||
-- do our static check, not at the time of its initial analysis).
|
||||
|
||||
-- However, we have to check calls within component definitions (e.g., a
|
||||
-- function call that determines an array component bound), so we
|
||||
-- However, we have to check calls within component definitions (e.g.
|
||||
-- a function call that determines an array component bound), so we
|
||||
-- terminate the loop in that case.
|
||||
|
||||
P := Parent (N);
|
||||
@ -1229,8 +1224,8 @@ package body Sem_Elab is
|
||||
if No (Outer_Scope) then
|
||||
Elab_Visited.Set_Last (0);
|
||||
|
||||
-- Nothing to do if current scope is Standard (this is a bit
|
||||
-- odd, but it happens in the case of generic instantiations).
|
||||
-- Nothing to do if current scope is Standard (this is a bit odd, but
|
||||
-- it happens in the case of generic instantiations).
|
||||
|
||||
C_Scope := Current_Scope;
|
||||
|
||||
@ -1243,9 +1238,8 @@ package body Sem_Elab is
|
||||
From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit;
|
||||
if From_Elab_Code then
|
||||
|
||||
-- Complain if call that comes from source in preelaborated
|
||||
-- unit and we are not inside a subprogram (i.e. we are in
|
||||
-- elab code)
|
||||
-- Complain if call that comes from source in preelaborated unit
|
||||
-- and we are not inside a subprogram (i.e. we are in elab code).
|
||||
|
||||
if Comes_From_Source (N)
|
||||
and then In_Preelaborated_Unit
|
||||
@ -1456,9 +1450,9 @@ package body Sem_Elab is
|
||||
|
||||
-- A call to an Init_Proc in elaboration code may bring additional
|
||||
-- dependencies, if some of the record components thereof have
|
||||
-- initializations that are function calls that come from source.
|
||||
-- We treat the current node as a call to each of these functions,
|
||||
-- to check their elaboration impact.
|
||||
-- initializations that are function calls that come from source. We
|
||||
-- treat the current node as a call to each of these functions, to check
|
||||
-- their elaboration impact.
|
||||
|
||||
if Is_Init_Proc (Ent)
|
||||
and then From_Elab_Code
|
||||
@ -1521,9 +1515,9 @@ package body Sem_Elab is
|
||||
Pkg_Body : Entity_Id;
|
||||
|
||||
begin
|
||||
-- For record or array component, check prefix. If it is an access
|
||||
-- type, then there is nothing to do (we do not know what is being
|
||||
-- assigned), but otherwise this is an assignment to the prefix.
|
||||
-- For record or array component, check prefix. If it is an access type,
|
||||
-- then there is nothing to do (we do not know what is being assigned),
|
||||
-- but otherwise this is an assignment to the prefix.
|
||||
|
||||
if Nkind (N) = N_Indexed_Component
|
||||
or else
|
||||
@ -1712,10 +1706,10 @@ package body Sem_Elab is
|
||||
|
||||
procedure Check_Elab_Calls is
|
||||
begin
|
||||
-- If expansion is disabled, do not generate any checks. Also
|
||||
-- skip checks if any subunits are missing because in either
|
||||
-- case we lack the full information that we need, and no object
|
||||
-- file will be created in any case.
|
||||
-- If expansion is disabled, do not generate any checks. Also skip
|
||||
-- checks if any subunits are missing because in either case we lack the
|
||||
-- full information that we need, and no object file will be created in
|
||||
-- any case.
|
||||
|
||||
if not Expander_Active
|
||||
or else Is_Generic_Unit (Cunit_Entity (Main_Unit))
|
||||
@ -1822,11 +1816,11 @@ package body Sem_Elab is
|
||||
Set_C_Scope;
|
||||
Check_A_Call (N, Ent, Scope (Ent), Inter_Unit_Only => False);
|
||||
|
||||
-- If none of those cases holds, but Dynamic_Elaboration_Checks mode
|
||||
-- is set, then we will do the check, but only in the inter-unit case
|
||||
-- (this is to accommodate unguarded elaboration calls from other units
|
||||
-- in which this same mode is set). We inhibit warnings in this case,
|
||||
-- since this instantiation is not occurring in elaboration code.
|
||||
-- If none of those cases holds, but Dynamic_Elaboration_Checks mode is
|
||||
-- set, then we will do the check, but only in the inter-unit case (this
|
||||
-- is to accommodate unguarded elaboration calls from other units in
|
||||
-- which this same mode is set). We inhibit warnings in this case, since
|
||||
-- this instantiation is not occurring in elaboration code.
|
||||
|
||||
elsif Dynamic_Elaboration_Checks then
|
||||
Set_C_Scope;
|
||||
@ -1882,10 +1876,10 @@ package body Sem_Elab is
|
||||
elsif not Full_Analysis then
|
||||
return;
|
||||
|
||||
-- Nothing to do if within a default expression, since the call
|
||||
-- is not actualy being made at this time.
|
||||
-- Nothing to do if analyzing in special spec-expression mode, since the
|
||||
-- call is not actualy being made at this time.
|
||||
|
||||
elsif In_Default_Expression then
|
||||
elsif In_Spec_Expression then
|
||||
return;
|
||||
|
||||
-- Nothing to do for call to intrinsic subprogram
|
||||
@ -1991,16 +1985,16 @@ package body Sem_Elab is
|
||||
Check_Elab_Instantiation (N, Outer_Scope);
|
||||
return OK;
|
||||
|
||||
-- Skip subprogram bodies that come from source (wait for
|
||||
-- call to analyze these). The reason for the come from
|
||||
-- source test is to avoid catching task bodies.
|
||||
-- Skip subprogram bodies that come from source (wait for call to
|
||||
-- analyze these). The reason for the come from source test is to
|
||||
-- avoid catching task bodies.
|
||||
|
||||
-- For task bodies, we should really avoid these too, waiting
|
||||
-- for the task activation, but that's too much trouble to
|
||||
-- catch for now, so we go in unconditionally. This is not
|
||||
-- so terrible, it means the error backtrace is not quite
|
||||
-- complete, and we are too eager to scan bodies of tasks
|
||||
-- that are unused, but this is hardly very significant!
|
||||
-- For task bodies, we should really avoid these too, waiting for the
|
||||
-- task activation, but that's too much trouble to catch for now, so
|
||||
-- we go in unconditionally. This is not so terrible, it means the
|
||||
-- error backtrace is not quite complete, and we are too eager to
|
||||
-- scan bodies of tasks that are unused, but this is hardly very
|
||||
-- significant!
|
||||
|
||||
elsif Nkind (N) = N_Subprogram_Body
|
||||
and then Comes_From_Source (N)
|
||||
@ -2051,8 +2045,8 @@ package body Sem_Elab is
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- If the body appears after the outer level call or
|
||||
-- instantiation then we have an error case handled below.
|
||||
-- If the body appears after the outer level call or instantiation then
|
||||
-- we have an error case handled below.
|
||||
|
||||
if Earlier_In_Extended_Unit (Outer_Level_Sloc, Sloc (Sbody))
|
||||
and then not In_Task_Activation
|
||||
@ -2065,8 +2059,8 @@ package body Sem_Elab is
|
||||
elsif Inst_Case then
|
||||
return;
|
||||
|
||||
-- Otherwise we have a call, so we trace through the called
|
||||
-- body to see if it has any problems ..
|
||||
-- Otherwise we have a call, so we trace through the called body to see
|
||||
-- if it has any problems.
|
||||
|
||||
else
|
||||
pragma Assert (Nkind (Sbody) = N_Subprogram_Body);
|
||||
@ -2083,9 +2077,9 @@ package body Sem_Elab is
|
||||
Write_Eol;
|
||||
end if;
|
||||
|
||||
-- Now traverse declarations and statements of subprogram body.
|
||||
-- Note that we cannot simply Traverse (Sbody), since traverse
|
||||
-- does not normally visit subprogram bodies.
|
||||
-- Now traverse declarations and statements of subprogram body. Note
|
||||
-- that we cannot simply Traverse (Sbody), since traverse does not
|
||||
-- normally visit subprogram bodies.
|
||||
|
||||
declare
|
||||
Decl : Node_Id;
|
||||
@ -2103,11 +2097,11 @@ package body Sem_Elab is
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Here is the case of calling a subprogram where the body has
|
||||
-- not yet been encountered, a warning message is needed.
|
||||
-- Here is the case of calling a subprogram where the body has not yet
|
||||
-- been encountered, a warning message is needed.
|
||||
|
||||
-- If we have nothing in the call stack, then this is at the
|
||||
-- outer level, and the ABE is bound to occur.
|
||||
-- If we have nothing in the call stack, then this is at the outer
|
||||
-- level, and the ABE is bound to occur.
|
||||
|
||||
if Elab_Call.Last = 0 then
|
||||
if Inst_Case then
|
||||
@ -2477,8 +2471,8 @@ package body Sem_Elab is
|
||||
and then Present (Parameter_Associations (Call))
|
||||
and then Is_Controlled (Etype (First_Actual (Call)));
|
||||
begin
|
||||
-- If the unit is mentioned in a with_clause of the current
|
||||
-- unit, it is visible, and we can set the elaboration flag.
|
||||
-- If the unit is mentioned in a with_clause of the current unit, it is
|
||||
-- visible, and we can set the elaboration flag.
|
||||
|
||||
if Is_Immediately_Visible (Scop)
|
||||
or else (Is_Child_Unit (Scop) and then Is_Visible_Child_Unit (Scop))
|
||||
@ -2505,9 +2499,9 @@ package body Sem_Elab is
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- If the unit is not in the context, there must be an intermediate
|
||||
-- unit that is, on which we need to place to elaboration flag. This
|
||||
-- happens with init proc calls.
|
||||
-- If the unit is not in the context, there must be an intermediate unit
|
||||
-- that is, on which we need to place to elaboration flag. This happens
|
||||
-- with init proc calls.
|
||||
|
||||
if Is_Init_Proc (Subp)
|
||||
or else Init_Call
|
||||
@ -2561,30 +2555,29 @@ package body Sem_Elab is
|
||||
|
||||
function Find_Body_In (E : Entity_Id; N : Node_Id) return Node_Id;
|
||||
-- Determine if the list of nodes headed by N and linked by Next
|
||||
-- contains a package body for the package spec entity E, and if
|
||||
-- so return the package body. If not, then returns Empty.
|
||||
-- contains a package body for the package spec entity E, and if so
|
||||
-- return the package body. If not, then returns Empty.
|
||||
|
||||
function Load_Package_Body (Nam : Unit_Name_Type) return Node_Id;
|
||||
-- This procedure is called load the unit whose name is given by Nam.
|
||||
-- This unit is being loaded to see whether it contains an optional
|
||||
-- generic body. The returned value is the loaded unit, which is
|
||||
-- always a package body (only package bodies can contain other
|
||||
-- entities in the sense in which Has_Generic_Body is interested).
|
||||
-- We only attempt to load bodies if we are generating code. If we
|
||||
-- are in semantics check only mode, then it would be wrong to load
|
||||
-- bodies that are not required from a semantic point of view, so
|
||||
-- in this case we return Empty. The result is that the caller may
|
||||
-- incorrectly decide that a generic spec does not have a body when
|
||||
-- in fact it does, but the only harm in this is that some warnings
|
||||
-- on elaboration problems may be lost in semantic checks only mode,
|
||||
-- which is not big loss. We also return Empty if we go for a body
|
||||
-- and it is not there.
|
||||
-- generic body. The returned value is the loaded unit, which is always
|
||||
-- a package body (only package bodies can contain other entities in the
|
||||
-- sense in which Has_Generic_Body is interested). We only attempt to
|
||||
-- load bodies if we are generating code. If we are in semantics check
|
||||
-- only mode, then it would be wrong to load bodies that are not
|
||||
-- required from a semantic point of view, so in this case we return
|
||||
-- Empty. The result is that the caller may incorrectly decide that a
|
||||
-- generic spec does not have a body when in fact it does, but the only
|
||||
-- harm in this is that some warnings on elaboration problems may be
|
||||
-- lost in semantic checks only mode, which is not big loss. We also
|
||||
-- return Empty if we go for a body and it is not there.
|
||||
|
||||
function Locate_Corresponding_Body (PE : Entity_Id) return Node_Id;
|
||||
-- PE is the entity for a package spec. This function locates the
|
||||
-- corresponding package body, returning Empty if none is found.
|
||||
-- The package body returned is fully parsed but may not yet be
|
||||
-- analyzed, so only syntactic fields should be referenced.
|
||||
-- corresponding package body, returning Empty if none is found. The
|
||||
-- package body returned is fully parsed but may not yet be analyzed,
|
||||
-- so only syntactic fields should be referenced.
|
||||
|
||||
------------------
|
||||
-- Find_Body_In --
|
||||
@ -2666,17 +2659,17 @@ package body Sem_Elab is
|
||||
begin
|
||||
if Is_Library_Level_Entity (PE) then
|
||||
|
||||
-- If package is a library unit that requires a body, we have
|
||||
-- no choice but to go after that body because it might contain
|
||||
-- an optional body for the original generic package.
|
||||
-- If package is a library unit that requires a body, we have no
|
||||
-- choice but to go after that body because it might contain an
|
||||
-- optional body for the original generic package.
|
||||
|
||||
if Unit_Requires_Body (PE) then
|
||||
|
||||
-- Load the body. Note that we are a little careful here to
|
||||
-- use Spec to get the unit number, rather than PE or Decl,
|
||||
-- since in the case where the package is itself a library
|
||||
-- level instantiation, Spec will properly reference the
|
||||
-- generic template, which is what we really want.
|
||||
-- Load the body. Note that we are a little careful here to use
|
||||
-- Spec to get the unit number, rather than PE or Decl, since
|
||||
-- in the case where the package is itself a library level
|
||||
-- instantiation, Spec will properly reference the generic
|
||||
-- template, which is what we really want.
|
||||
|
||||
return
|
||||
Load_Package_Body
|
||||
@ -3041,8 +3034,55 @@ package body Sem_Elab is
|
||||
declare
|
||||
Ent : constant Entity_Id := Defining_Unit_Name (Specification (N));
|
||||
begin
|
||||
Set_Is_Imported (Ent);
|
||||
Set_Convention (Ent, Convention_Stubbed);
|
||||
|
||||
-- Internal subprograms will already have a generated body, so
|
||||
-- there is no need to provide a stub for them.
|
||||
|
||||
if No (Corresponding_Body (N)) then
|
||||
declare
|
||||
Loc : constant Source_Ptr := Sloc (N);
|
||||
B : Node_Id;
|
||||
Formals : constant List_Id :=
|
||||
Copy_Parameter_List (Ent);
|
||||
Nam : constant Entity_Id :=
|
||||
Make_Defining_Identifier (Loc, Chars (Ent));
|
||||
Spec : Node_Id;
|
||||
Stats : constant List_Id :=
|
||||
New_List
|
||||
(Make_Raise_Program_Error (Loc,
|
||||
Reason => PE_Access_Before_Elaboration));
|
||||
begin
|
||||
if Ekind (Ent) = E_Function then
|
||||
Spec :=
|
||||
Make_Function_Specification (Loc,
|
||||
Defining_Unit_Name => Nam,
|
||||
Parameter_Specifications => Formals,
|
||||
Result_Definition =>
|
||||
New_Copy_Tree
|
||||
(Result_Definition (Specification (N))));
|
||||
|
||||
-- We cannot reliably make a return statement for this
|
||||
-- body, but none is needed because the call raises
|
||||
-- program error.
|
||||
|
||||
Set_Return_Present (Ent);
|
||||
|
||||
else
|
||||
Spec :=
|
||||
Make_Procedure_Specification (Loc,
|
||||
Defining_Unit_Name => Nam,
|
||||
Parameter_Specifications => Formals);
|
||||
end if;
|
||||
|
||||
B := Make_Subprogram_Body (Loc,
|
||||
Specification => Spec,
|
||||
Declarations => New_List,
|
||||
Handled_Statement_Sequence =>
|
||||
Make_Handled_Sequence_Of_Statements (Loc, Stats));
|
||||
Insert_After (N, B);
|
||||
Analyze (B);
|
||||
end;
|
||||
end if;
|
||||
end;
|
||||
|
||||
elsif Nkind (N) = N_Package_Declaration then
|
||||
@ -3075,22 +3115,17 @@ package body Sem_Elab is
|
||||
|
||||
function Within (E1, E2 : Entity_Id) return Boolean is
|
||||
Scop : Entity_Id;
|
||||
|
||||
begin
|
||||
Scop := E1;
|
||||
loop
|
||||
if Scop = E2 then
|
||||
return True;
|
||||
|
||||
elsif Scop = Standard_Standard then
|
||||
return False;
|
||||
|
||||
else
|
||||
Scop := Scope (Scop);
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
raise Program_Error;
|
||||
end Within;
|
||||
|
||||
--------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user