home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
sem_ch11.adb
< prev
next >
Wrap
Text File
|
1996-09-28
|
9KB
|
254 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S E M _ C H 1 1 --
-- --
-- B o d y --
-- --
-- $Revision: 1.47 $ --
-- --
-- Copyright (c) 1992,1993,1994 NYU, All Rights Reserved --
-- --
-- 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- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with Atree; use Atree;
with Einfo; use Einfo;
with Errout; use Errout;
with Features; use Features;
with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
with Opt; use Opt;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Ch5; use Sem_Ch5;
with Sem_Ch8; use Sem_Ch8;
with Sem_Dist; use Sem_Dist;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Stand; use Stand;
package body Sem_Ch11 is
-----------------------------------
-- Analyze_Exception_Declaration --
-----------------------------------
procedure Analyze_Exception_Declaration (N : Node_Id) is
Id : constant Entity_Id := Defining_Identifier (N);
PF : constant Boolean := Is_Pure (Current_Scope);
begin
Enter_Name (Id);
Set_Ekind (Id, E_Exception);
Set_Etype (Id, Standard_Exception_Type);
-- Entities declared in Pure unit should be set Is_Pure
-- Since 'Partition_Id cannot be applied to such an entity
Set_Is_Pure (Id, PF);
end Analyze_Exception_Declaration;
--------------------------------
-- Analyze_Handled_Statements --
--------------------------------
procedure Analyze_Handled_Statements (N : Node_Id) is
Handlers : constant List_Id := Exception_Handlers (N);
begin
Analyze_Statements (Statements (N));
if Present (Handlers) then
Analyze_Exception_Handlers (Handlers);
elsif Present (Identifier (N)) then
Analyze (Identifier (N));
end if;
end Analyze_Handled_Statements;
--------------------------------
-- Analyze_Exception_Handlers --
--------------------------------
procedure Analyze_Exception_Handlers (L : List_Id) is
Handler : Node_Id;
Choice : Entity_Id;
Id : Node_Id;
procedure Check_Duplication (Id : Node_Id);
-- Iterate through the identifiers in each handler to find duplicates
procedure Check_Duplication (Id : Node_Id) is
Handler : Node_Id;
Id1 : Node_Id;
begin
Handler := First (L);
while Present (Handler) loop
Id1 := First (Exception_Choices (Handler));
while Present (Id1) loop
-- Only check against the exception choices which precede
-- Id in the handler, since the ones that follow Id have not
-- been analyzed yet and will be checked in a subsequent call.
if Id = Id1 then
return;
elsif Nkind (Id1) /= N_Others_Choice
and then Entity (Id) = Entity (Id1)
then
if Handler /= Parent (Id) then
Error_Msg_N ("duplicate exception choice&", Id);
else
Note_Feature (Exception_Choices, Sloc (Id));
if Ada_83 and then Comes_From_Source (Id) then
Error_Msg_N
("(Ada 83): duplicate exception choice&", Id);
end if;
end if;
end if;
Id1 := Next (Id1);
end loop;
Handler := Next (Handler);
end loop;
end Check_Duplication;
-- Start processing for Analyze_Exception_Handlers
begin
Handler := First (L);
while Present (Handler) loop
Id := First (Exception_Choices (Handler));
while Present (Id) loop
if Nkind (Id) = N_Others_Choice then
if Present (Next (Id))
or else Present (Next (Handler))
or else Present (Prev (Id))
then
Error_Msg_N ("OTHERS must appear alone and last", Id);
end if;
else
Analyze (Id);
if Is_Entity_Name (Id)
and then Present (Renamed_Object (Entity (Id)))
then
Set_Entity (Id, Renamed_Object (Entity (Id)));
end if;
if not Is_Entity_Name (Id)
or else Ekind (Entity (Id)) /= E_Exception
then
Error_Msg_N ("exception name expected", Id);
else
Check_Duplication (Id);
end if;
end if;
Id := Next (Id);
end loop;
Choice := Choice_Parameter (Handler);
if Present (Choice) then
Enter_Name (Choice);
Set_Ekind (Choice, E_Variable);
Set_Etype (Choice, RTE (RE_Exception_Occurrence));
end if;
Analyze_Statements (Statements (Handler));
Handler := Next (Handler);
end loop;
end Analyze_Exception_Handlers;
-----------------------------
-- Analyze_Raise_Statement --
-----------------------------
procedure Analyze_Raise_Statement (N : Node_Id) is
Exception_Id : constant Node_Id := Name (N);
Exception_Name : Entity_Id := Empty;
P : Node_Id;
Nkind_P : Node_Kind;
begin
-- Reraise statement
if No (Exception_Id) then
P := Parent (N);
Nkind_P := Nkind (P);
while Nkind_P /= N_Exception_Handler
and then Nkind_P /= N_Subprogram_Body
and then Nkind_P /= N_Package_Body
and then Nkind_P /= N_Task_Body
and then Nkind_P /= N_Entry_Body
loop
P := Parent (P);
Nkind_P := Nkind (P);
end loop;
if Nkind (P) /= N_Exception_Handler then
Error_Msg_N
("reraise statement must appear directly in a handler", N);
end if;
-- Normal case with exception id present
else
Analyze (Exception_Id);
if Is_Entity_Name (Exception_Id) then
Exception_Name := Entity (Exception_Id);
if Present (Renamed_Object (Exception_Name)) then
Set_Entity (Exception_Id, Renamed_Object (Exception_Name));
end if;
end if;
if No (Exception_Name)
or else Ekind (Exception_Name) /= E_Exception
then
Error_Msg_N
("exception name expected in raise statement", Exception_Id);
end if;
-- If raise appears in System-Finalization_Implementation, then
-- set the No_Defer flag. The reason is that we already deferred
-- abort on entering the finalization routine, and we must not
-- do an additional defer as the result of raising program error.
Get_Name_String (Unit_Name (Get_Sloc_Unit_Number (Sloc (N))));
if Name_Buffer (1 .. 24) = "system.finalization_impl" then
Set_No_Defer (N);
end if;
end if;
end Analyze_Raise_Statement;
end Sem_Ch11;