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_ch9.adb
< prev
next >
Wrap
Text File
|
1996-09-28
|
31KB
|
1,015 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S E M _ C H 9 --
-- --
-- B o d y --
-- --
-- $Revision: 1.127 $ --
-- --
-- Copyright (c) 1992,1993,1994,1995 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 Exp_Ch7; use Exp_Ch7;
with Exp_Ch9;
with Elists; use Elists;
with Features; use Features;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Opt; use Opt;
with Output; use Output;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch4; use Sem_Ch4;
with Sem_Ch5; use Sem_Ch5;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Dist; use Sem_Dist;
with Sem_Res; use Sem_Res;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Stand; use Stand;
with Sinfo; use Sinfo;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
package body Sem_Ch9 is
-----------------------
-- Local Subprograms --
-----------------------
function Find_Concurrent_Spec (Body_Id : Entity_Id) return Entity_Id;
-- Find entity in corresponding task or protected declaration. Use full
-- view if first declaration was for an incomplete type.
procedure Install_Declarations (Spec : Entity_Id);
-- Utility to make visible in corresponding body the entities defined
-- in task, protected type declaration, or entry declaration.
-----------------------------
-- Analyze_Abort_Statement --
-----------------------------
procedure Analyze_Abort_Statement (N : Node_Id) is
T_Name : Node_Id;
begin
T_Name := First (Names (N));
while Present (T_Name) loop
Analyze (T_Name);
if not Is_Task_Type (Etype (T_Name)) then
Error_Msg_N ("expect task name for ABORT", T_Name);
return;
else
Resolve (T_Name, Etype (T_Name));
end if;
T_Name := Next (T_Name);
end loop;
end Analyze_Abort_Statement;
----------------------------
-- Analyze_Abortable_Part --
----------------------------
procedure Analyze_Abortable_Part (N : Node_Id) is
begin
Unimplemented (N, "abortable part");
end Analyze_Abortable_Part;
---------------------------------
-- Analyze_Accept_Alternative --
---------------------------------
procedure Analyze_Accept_Alternative (N : Node_Id) is
begin
Analyze (Accept_Statement (N));
if Present (Condition (N)) then
Analyze (Condition (N));
Resolve (Condition (N), Any_Boolean);
end if;
if Is_Non_Empty_List (Statements (N)) then
Analyze_Statements (Statements (N));
end if;
end Analyze_Accept_Alternative;
------------------------------
-- Analyze_Accept_Statement --
------------------------------
procedure Analyze_Accept_Statement (N : Node_Id) is
Nam : constant Entity_Id := Entry_Direct_Name (N);
Formals : constant List_Id := Parameter_Specifications (N);
Index : constant Node_Id := Entry_Index (N);
Stats : constant Node_Id := Handled_Statement_Sequence (N);
Ityp : Entity_Id;
Entry_Nam : Entity_Id;
E : Entity_Id;
Kind : Entity_Kind;
Task_Nam : Entity_Id;
begin
-- Entry name is initialized to Any_Id. It should get reset to the
-- matching entry entity. An error is signalled if it is not reset.
Entry_Nam := Any_Id;
for J in reverse 0 .. Scope_Stack.Last loop
Task_Nam := Scope_Stack.Table (J).Entity;
exit when Ekind (Etype (Task_Nam)) = E_Task_Type;
Kind := Ekind (Task_Nam);
if Kind /= E_Block and then Kind /= E_Loop
and then Kind /= E_Entry and then Kind /= E_Entry_Family
then
Error_Msg_N ("enclosing body of accept must be a task", N);
return;
end if;
end loop;
if Ekind (Etype (Task_Nam)) /= E_Task_Type then
Error_Msg_N ("invalid context for accept statement", N);
return;
end if;
-- In order to process the parameters, we create a defining
-- identifier that can be used as the name of the scope. The
-- name of the accept statement itself is not a defining identifier.
if Present (Index) then
Ityp := New_Internal_Entity
(E_Entry_Family, Current_Scope, Sloc (N), 'E');
else
Ityp := New_Internal_Entity
(E_Entry, Current_Scope, Sloc (N), 'E');
end if;
Set_Etype (Ityp, Standard_Void_Type);
Set_Accept_Address (Ityp, New_Elmt_List);
if Present (Formals) then
New_Scope (Ityp);
Process_Formals (Ityp, Formals, N);
End_Scope;
end if;
E := First_Entity (Etype (Task_Nam));
while Present (E) loop
if Chars (E) = Chars (Nam)
and then (Ekind (E) = Ekind (Ityp))
and then Type_Conformant (Ityp, E)
then
Entry_Nam := E;
exit;
end if;
E := Next_Entity (E);
end loop;
if Entry_Nam = Any_Id then
Error_Msg_N ("no entry declaration matches accept statement", N);
return;
else
Set_Entity (Nam, Entry_Nam);
end if;
Check_Fully_Conformant (Ityp, Entry_Nam, N);
for J in reverse 0 .. Scope_Stack.Last loop
exit when Task_Nam = Scope_Stack.Table (J).Entity;
if Entry_Nam = Scope_Stack.Table (J).Entity then
Error_Msg_N ("duplicate accept statement for same entry", N);
end if;
end loop;
if Ekind (E) = E_Entry_Family then
if No (Index) then
Error_Msg_N ("missing entry index in accept for entry family", N);
else
Analyze (Index);
Resolve (Index, Etype (Discrete_Subtype_Definition (Parent (E))));
end if;
elsif Present (Index) then
Error_Msg_N ("invalid entry index in accept for simple entry", N);
end if;
-- If statements are present, they must be analyzed in the context
-- of the entry, so that references to formals are correcly resolved.
-- We also have to add the declarations that are required by the
-- expansion of the accept statement in this case if expansion active.
-- In the case of a select alternative of a selective accept,
-- the expander references the address declaration even if there
-- is no statement list.
Exp_Ch9.Expand_Accept_Declarations (N, Entry_Nam);
if Present (Stats) then
New_Scope (Entry_Nam);
Install_Declarations (Entry_Nam);
Set_Actual_Subtypes (N, Current_Scope);
Analyze (Stats);
End_Scope;
end if;
end Analyze_Accept_Statement;
---------------------------------
-- Analyze_Asynchronous_Select --
---------------------------------
procedure Analyze_Asynchronous_Select (N : Node_Id) is
begin
Analyze (Triggering_Alternative (N));
Analyze_Statements (Statements (Abortable_Part (N)));
end Analyze_Asynchronous_Select;
------------------------------------
-- Analyze_Conditional_Entry_Call --
------------------------------------
procedure Analyze_Conditional_Entry_Call (N : Node_Id) is
begin
Analyze (Entry_Call_Alternative (N));
Analyze_Statements (Else_Statements (N));
end Analyze_Conditional_Entry_Call;
--------------------------------
-- Analyze_Delay_Alternative --
--------------------------------
procedure Analyze_Delay_Alternative (N : Node_Id) is
begin
if Nkind (Parent (N)) = N_Selective_Accept then
Analyze (Expression (Delay_Statement (N)));
else
Analyze (Delay_Statement (N));
end if;
if Present (Condition (N)) then
Analyze (Condition (N));
Resolve (Condition (N), Any_Boolean);
end if;
if Is_Non_Empty_List (Statements (N)) then
Analyze_Statements (Statements (N));
end if;
end Analyze_Delay_Alternative;
----------------------------
-- Analyze_Delay_Relative --
----------------------------
procedure Analyze_Delay_Relative (N : Node_Id) is
E : constant Node_Id := Expression (N);
begin
Analyze (E);
Resolve (E, Standard_Duration);
end Analyze_Delay_Relative;
-------------------------
-- Analyze_Delay_Until --
-------------------------
procedure Analyze_Delay_Until (N : Node_Id) is
E : constant Node_Id := Expression (N);
begin
Analyze (E);
if Etype (E) /= Etype (RTE (RO_CA_Time)) and then
Etype (E) /= Etype (RTE (RO_RT_Time))
then
Error_Msg_N ("expect Time types for `delay until`", E);
end if;
end Analyze_Delay_Until;
------------------------
-- Analyze_Entry_Body --
------------------------
procedure Analyze_Entry_Body (N : Node_Id) is
Id : constant Entity_Id := Defining_Identifier (N);
Decls : constant List_Id := Declarations (N);
Stats : constant Node_Id := Handled_Statement_Sequence (N);
Entry_Name : Entity_Id;
E : Entity_Id;
begin
-- Entry_Name is initialized to Any_Id. It should get reset to the
-- matching entry entity. An error is signalled if it is not reset
Entry_Name := Any_Id;
Analyze (Entry_Body_Formal_Part (N));
if Present (Entry_Index_Specification (Entry_Body_Formal_Part (N))) then
Set_Ekind (Id, E_Entry_Family);
else
Set_Ekind (Id, E_Entry);
end if;
Set_Etype (Id, Standard_Void_Type);
Set_Accept_Address (Id, New_Elmt_List);
E := First_Entity (Current_Scope);
while Present (E) loop
if Chars (E) = Chars (Id)
and then (Ekind (E) = Ekind (Id))
and then Type_Conformant (Id, E)
then
Entry_Name := E;
Check_Fully_Conformant (Id, E, N);
exit;
end if;
E := Next_Entity (E);
end loop;
if Entry_Name = Any_Id then
Error_Msg_N ("no entry declaration matches entry body", N);
return;
else
Set_Has_Completion (Entry_Name);
end if;
Exp_Ch9.Expand_Entry_Barrier (N);
New_Scope (Entry_Name);
Set_Actual_Subtypes (N, Current_Scope);
Exp_Ch9.Expand_Entry_Body_Declarations (N);
if Present (Decls) then
Install_Declarations (Entry_Name);
Analyze_Declarations (Decls);
end if;
if Present (Stats) then
Analyze (Stats);
end if;
End_Scope;
end Analyze_Entry_Body;
------------------------------------
-- Analyze_Entry_Body_Formal_Part --
------------------------------------
procedure Analyze_Entry_Body_Formal_Part (N : Node_Id) is
Id : constant Entity_Id := Defining_Identifier (Parent (N));
Index : constant Node_Id := Entry_Index_Specification (N);
Formals : constant List_Id := Parameter_Specifications (N);
Cond : constant Node_Id := Condition (N);
begin
if Present (Cond) then
Analyze (Cond);
Resolve (Cond, Any_Boolean);
end if;
if Present (Index) then
Analyze (Index);
end if;
if Present (Formals) then
Set_Scope (Id, Current_Scope);
New_Scope (Id);
Process_Formals (Id, Formals, Parent (N));
End_Scope;
end if;
end Analyze_Entry_Body_Formal_Part;
------------------------------------
-- Analyze_Entry_Call_Alternative --
------------------------------------
procedure Analyze_Entry_Call_Alternative (N : Node_Id) is
begin
Analyze (Entry_Call_Statement (N));
if Is_Non_Empty_List (Statements (N)) then
Analyze_Statements (Statements (N));
end if;
end Analyze_Entry_Call_Alternative;
-------------------------------
-- Analyze_Entry_Declaration --
-------------------------------
procedure Analyze_Entry_Declaration (N : Node_Id) is
Id : Entity_Id := Defining_Identifier (N);
D_Sdef : Node_Id := Discrete_Subtype_Definition (N);
Formals : List_Id := Parameter_Specifications (N);
Task_Ent : Entity_Id := Current_Scope;
begin
if No (D_Sdef) then
Set_Ekind (Id, E_Entry);
else
Enter_Name (Id);
Set_Ekind (Id, E_Entry_Family);
Analyze (D_Sdef);
Make_Index (D_Sdef, N, Id);
end if;
Set_Etype (Id, Standard_Void_Type);
Set_Accept_Address (Id, New_Elmt_List);
if Present (Formals) then
Set_Scope (Id, Current_Scope);
New_Scope (Id);
Process_Formals (Id, Formals, N);
End_Scope;
end if;
if Ekind (Id) = E_Entry then
New_Overloaded_Entity (Id);
end if;
end Analyze_Entry_Declaration;
---------------------------------------
-- Analyze_Entry_Index_Specification --
---------------------------------------
-- ??? Cargo cult, adapted from for loop iterator analysis.
-- To make this work, I put N_Entry_Index_Specification
-- in the N_Has_Itypes set. I am not sure that this
-- is correct; there is already an Itype associated with
-- the declaration of the entry family. However,
-- the N_Entry_Index_Specification node is associated with
-- then N_Entry_Body node, and it is not at all easy to
-- get to the corresponding N_Entry_Family node from
-- here. I am not sure it is worth the effort unless there
-- is some overriding reason to use the Itype associated
-- with the N_Entry_Family node.
procedure Analyze_Entry_Index_Specification (N : Node_Id) is
Iden : constant Node_Id := Defining_Identifier (N);
Def : constant Node_Id := Discrete_Subtype_Definition (N);
begin
Analyze (Def);
Make_Index (Def, N);
Enter_Name (Iden);
Set_Ekind (Iden, E_Entry_Index_Parameter);
Set_Etype (Iden, Etype (Def));
end Analyze_Entry_Index_Specification;
----------------------------
-- Analyze_Protected_Body --
----------------------------
procedure Analyze_Protected_Body (N : Node_Id) is
Body_Id : constant Entity_Id := Defining_Identifier (N);
Spec_Id : Entity_Id;
begin
Set_Ekind (Body_Id, E_Protected_Body);
Spec_Id := Find_Concurrent_Spec (Body_Id);
if No (Spec_Id)
or else Ekind (Etype (Spec_Id)) /= E_Protected_Type
then
Error_Msg_N ("missing specification for protected body", Body_Id);
return;
end if;
-- The declarations are always attached to the type
if Ekind (Spec_Id) /= E_Protected_Type then
Spec_Id := Etype (Spec_Id);
end if;
New_Scope (Spec_Id);
Set_Corresponding_Spec (N, Spec_Id);
Set_Corresponding_Body (Parent (Spec_Id), Body_Id);
Set_Has_Completion (Spec_Id);
Install_Declarations (Spec_Id);
Exp_Ch9.Expand_Protected_Body_Declarations (N, Spec_Id);
Analyze_Declarations (Declarations (N));
Check_Completion (Body_Id);
End_Scope;
end Analyze_Protected_Body;
----------------------------------
-- Analyze_Protected_Definition --
----------------------------------
procedure Analyze_Protected_Definition (N : Node_Id) is
L : Entity_Id;
begin
Analyze_Declarations (Visible_Declarations (N));
if Present (Private_Declarations (N))
and then not Is_Empty_List (Private_Declarations (N))
then
L := Last_Entity (Current_Scope);
Analyze_Declarations (Private_Declarations (N));
Set_First_Private_Entity (Current_Scope, Next_Entity (L));
end if;
end Analyze_Protected_Definition;
----------------------------
-- Analyze_Protected_Type --
----------------------------
procedure Analyze_Protected_Type (N : Node_Id) is
E : Entity_Id;
T : Entity_Id;
begin
T := Find_Type_Name (N);
Set_Ekind (T, E_Protected_Type);
Set_Etype (T, T);
Set_Has_Controlled (T, Is_Controlled (RTE (RE_Protection)));
Set_Is_First_Subtype (T, True);
Set_Has_Delayed_Freeze (T, True);
New_Scope (T);
-- RCI unit (user source) specification cannot have limited
-- type declaration (RM E.2.3(10))
if Comes_From_Source (T) then
Validate_RCI_Limited_Type_Declaration (N);
end if;
if Present (Discriminant_Specifications (N)) then
Process_Discriminants (N);
end if;
Analyze (Protected_Definition (N));
-- The Ekind of components is E_Void during analysis to detect
-- illegal uses. Now it can be set correctly.
E := First_Entity (Current_Scope);
while Present (E) loop
if Ekind (E) = E_Void then
Set_Ekind (E, E_Component);
end if;
E := Next_Entity (E);
end loop;
End_Scope;
end Analyze_Protected_Type;
---------------------
-- Analyze_Requeue --
---------------------
procedure Analyze_Requeue (N : Node_Id) is
Entry_Name : Node_Id := Name (N);
Entry_Id : Entity_Id;
Found : Boolean;
I : Interp_Index;
It : Interp;
Enclosing : Entity_Id;
begin
Enclosing := Current_Scope;
loop
if Ekind (Enclosing) = E_Entry
or else Ekind (Enclosing) = E_Entry_Family
then
exit;
elsif Ekind (Enclosing) = E_Loop
or else Ekind (Enclosing) = E_Block
then
Enclosing := Scope (Enclosing);
else
Error_Msg_N ("requeue must appear within accept or entry body", N);
return;
end if;
end loop;
Analyze (Entry_Name);
if Etype (Entry_Name) = Any_Type then
return;
end if;
if Nkind (Entry_Name) = N_Selected_Component then
Entry_Name := Selector_Name (Entry_Name);
end if;
-- Overloaded case, find right interpretation
if Is_Overloaded (Entry_Name) then
Get_First_Interp (Entry_Name, I, It);
Found := False;
while Present (It.Nam) loop
if No (First_Formal (It.Nam))
or else Subtype_Conformant (Enclosing, It.Nam)
then
if not Found then
Found := True;
Entry_Id := It.Nam;
else
Error_Msg_N ("ambiguous entry name in requeue", N);
return;
end if;
end if;
Get_Next_Interp (I, It);
end loop;
if not Found then
Error_Msg_N ("no entry matches context", N);
return;
else
Set_Entity (Entry_Name, Entry_Id);
end if;
-- Non-overloaded cases
-- For the case of a reference to an element of an entry family,
-- the Entry_Name is an indexed component.
elsif Nkind (Entry_Name) = N_Indexed_Component then
-- Requeue to an entry out of the body
if Nkind (Prefix (Entry_Name)) = N_Selected_Component then
Entry_Id := Entity (Selector_Name (Prefix (Entry_Name)));
-- Requeue from within the body itself
elsif Nkind (Prefix (Entry_Name)) = N_Identifier then
Entry_Id := Entity (Prefix (Entry_Name));
else
Error_Msg_N ("invalid entry_name specified", N);
return;
end if;
else
Entry_Id := Entity (Entry_Name);
end if;
-- Resolve entry, and check that it is subtype conformant with the
-- enclosing construct if this construct has formals (RM 9.5.4(5)).
Resolve_Entry (Name (N));
if Present (First_Formal (Entry_Id)) then
Check_Subtype_Conformant (Enclosing, Entry_Id, Name (N));
end if;
end Analyze_Requeue;
------------------------------
-- Analyze_Selective_Accept --
------------------------------
procedure Analyze_Selective_Accept (N : Node_Id) is
Alts : constant List_Id := Select_Alternatives (N);
Alt : Node_Id;
Accept_Present : Boolean := False;
Terminate_Present : Boolean := False;
Delay_Present : Boolean := False;
begin
Alt := First (Alts);
while Present (Alt) loop
Analyze (Alt);
if Nkind (Alt) = N_Delay_Alternative then
Delay_Present := True;
elsif Nkind (Alt) = N_Terminate_Alternative then
if Terminate_Present then
Error_Msg_N ("Only one terminate alternative allowed", N);
else
Terminate_Present := True;
end if;
else
Accept_Present := True;
end if;
Alt := Next (Alt);
end loop;
if Terminate_Present and Delay_Present then
Error_Msg_N ("at most one of terminate or delay alternative", N);
elsif not Accept_Present then
Error_Msg_N
("select must contain at least one accept alternative", N);
end if;
if Present (Else_Statements (N)) then
if Terminate_Present or Delay_Present then
Error_Msg_N ("else part not allowed with other alternatives", N);
end if;
Analyze_Statements (Else_Statements (N));
end if;
end Analyze_Selective_Accept;
------------------------------
-- Analyze_Single_Protected --
------------------------------
procedure Analyze_Single_Protected (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Id : constant Node_Id := Defining_Identifier (N);
T : Entity_Id;
T_Decl : Node_Id;
O_Decl : Node_Id;
begin
-- The node is rewritten as a protected type declaration,
-- in exact analogy with what is done with single tasks.
T :=
Make_Defining_Identifier (Loc,
New_External_Name (Chars (Id), 'T'));
T_Decl :=
Make_Protected_Type_Declaration (Loc,
Defining_Identifier => T,
Protected_Definition => Relocate_Node (Protected_Definition (N)));
O_Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => New_Copy (Id),
Object_Definition => Make_Identifier (Loc, Chars (T)));
Rewrite_Substitute_Tree (N, T_Decl);
Insert_After (N, O_Decl);
Mark_Rewrite_Insertion (O_Decl);
-- Instead of calling Analyze on the new node, call directly
-- the proper analysis procedure. Otherwise the node would be
-- expanded twice, with disastrous result.
Analyze_Protected_Type (N);
end Analyze_Single_Protected;
-------------------------
-- Analyze_Single_Task --
-------------------------
procedure Analyze_Single_Task (N : Node_Id) is
Id : constant Node_Id := Defining_Identifier (N);
Loc : constant Source_Ptr := Sloc (N);
T : Entity_Id;
T_Decl : Node_Id;
O_Decl : Node_Id;
begin
-- The node is rewritten as a task type declaration, followed
-- by an object declaration of that anonymous task type.
T :=
Make_Defining_Identifier (Loc,
New_External_Name (Chars (Id), 'T'));
T_Decl :=
Make_Task_Type_Declaration (Loc,
Defining_Identifier => T,
Task_Definition => Relocate_Node (Task_Definition (N)));
O_Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => New_Copy (Id),
Object_Definition => Make_Identifier (Loc, Chars (T)));
Rewrite_Substitute_Tree (N, T_Decl);
Insert_After (N, O_Decl);
Mark_Rewrite_Insertion (O_Decl);
-- Instead of calling Analyze on the new node, call directly
-- the proper analysis procedure. Otherwise the node would be
-- expanded twice, with disastrous result.
Analyze_Task_Type (N);
end Analyze_Single_Task;
-----------------------
-- Analyze_Task_Body --
-----------------------
procedure Analyze_Task_Body (N : Node_Id) is
Body_Id : constant Entity_Id := Defining_Identifier (N);
Spec_Id : Entity_Id;
begin
Set_Ekind (Body_Id, E_Task_Body);
Spec_Id := Find_Concurrent_Spec (Body_Id);
if No (Spec_Id)
or else Ekind (Etype (Spec_Id)) /= E_Task_Type
then
Error_Msg_N ("missing specification for task body", Body_Id);
return;
end if;
-- Deal with case of body of single task (anonymous type was created)
if Ekind (Spec_Id) = E_Variable then
Spec_Id := Etype (Spec_Id);
end if;
New_Scope (Spec_Id);
Set_Corresponding_Spec (N, Spec_Id);
Set_Corresponding_Body (Parent (Spec_Id), Body_Id);
Set_Has_Completion (Spec_Id);
Install_Declarations (Spec_Id);
Analyze_Declarations (Declarations (N));
Analyze (Handled_Statement_Sequence (N));
Check_Completion (Body_Id);
End_Scope;
end Analyze_Task_Body;
-----------------------------
-- Analyze_Task_Definition --
-----------------------------
procedure Analyze_Task_Definition (N : Node_Id) is
L : Entity_Id;
E_Index : Uint;
begin
if Present (Visible_Declarations (N)) then
Analyze_Declarations (Visible_Declarations (N));
end if;
if Present (Private_Declarations (N)) then
L := Last_Entity (Current_Scope);
Analyze_Declarations (Private_Declarations (N));
if Present (L) then
Set_First_Private_Entity
(Current_Scope, Next_Entity (L));
else
Set_First_Private_Entity
(Current_Scope, First_Entity (Current_Scope));
end if;
end if;
end Analyze_Task_Definition;
-----------------------
-- Analyze_Task_Type --
-----------------------
procedure Analyze_Task_Type (N : Node_Id) is
T : Entity_Id;
begin
T := Find_Type_Name (N);
Set_Ekind (T, E_Task_Type);
Set_Is_First_Subtype (T, True);
Set_Has_Tasks (T, True);
Set_Esize (T, UI_From_Int (System_Address_Size));
Set_Etype (T, T);
Set_Has_Delayed_Freeze (T, True);
New_Scope (T);
-- RCI unit (user source) specification cannot have limited type
-- declaration. (RM E.2.3(10)).
if Comes_From_Source (T) then
Validate_RCI_Limited_Type_Declaration (N);
end if;
if Present (Discriminant_Specifications (N)) then
Note_Feature (Task_Discriminants, Sloc (N));
if Ada_83 and then Comes_From_Source (N) then
Error_Msg_N ("(Ada 83) task discriminant not allowed!", N);
end if;
Process_Discriminants (N);
end if;
if Present (Task_Definition (N)) then
Analyze_Task_Definition (Task_Definition (N));
end if;
End_Scope;
end Analyze_Task_Type;
-----------------------------------
-- Analyze_Terminate_Alternative --
-----------------------------------
procedure Analyze_Terminate_Alternative (N : Node_Id) is
begin
if Present (Condition (N)) then
Analyze (Condition (N));
Resolve (Condition (N), Any_Boolean);
end if;
end Analyze_Terminate_Alternative;
------------------------------
-- Analyze_Timed_Entry_Call --
------------------------------
procedure Analyze_Timed_Entry_Call (N : Node_Id) is
begin
Analyze (Entry_Call_Alternative (N));
Analyze (Delay_Alternative (N));
end Analyze_Timed_Entry_Call;
------------------------------------
-- Analyze_Triggering_Alternative --
------------------------------------
procedure Analyze_Triggering_Alternative (N : Node_Id) is
begin
Analyze (Triggering_Statement (N));
if Is_Non_Empty_List (Statements (N)) then
Analyze_Statements (Statements (N));
end if;
end Analyze_Triggering_Alternative;
--------------------------
-- Find_Concurrent_Spec --
--------------------------
function Find_Concurrent_Spec (Body_Id : Entity_Id) return Entity_Id is
Spec_Id : Entity_Id := Current_Entity_In_Scope (Body_Id);
begin
-- The type may have been given by an incomplete type declaration.
-- Find full view now.
if Present (Spec_Id) and then Ekind (Spec_Id) = E_Incomplete_Type then
Spec_Id := Full_View (Spec_Id);
end if;
return Spec_Id;
end Find_Concurrent_Spec;
--------------------------
-- Install_Declarations --
--------------------------
procedure Install_Declarations (Spec : Entity_Id) is
E : Entity_Id;
Prev : Entity_Id;
begin
E := First_Entity (Spec);
while Present (E) loop
Prev := Current_Entity (E);
Set_Current_Entity (E);
Set_Is_Immediately_Visible (E);
Set_Homonym (E, Prev);
E := Next_Entity (E);
end loop;
end Install_Declarations;
begin
null;
end Sem_Ch9;