summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch10.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch10.adb')
-rw-r--r--gcc/ada/sem_ch10.adb349
1 files changed, 276 insertions, 73 deletions
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 665c1efb861..bd9b5746f3c 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -28,6 +28,7 @@ with Debug; use Debug;
with Einfo; use Einfo;
with Errout; use Errout;
with Exp_Util; use Exp_Util;
+with Elists; use Elists;
with Fname; use Fname;
with Fname.UF; use Fname.UF;
with Freeze; use Freeze;
@@ -1247,6 +1248,16 @@ package body Sem_Ch10 is
Next (Item);
end loop;
+ -- This is the point at which we capture the configuration settings
+ -- for the unit. At the moment only the Optimize_Alignment setting
+ -- needs to be captured. Probably more later ???
+
+ if Optimize_Alignment_Local then
+ Set_OA_Setting (Current_Sem_Unit, 'L');
+ else
+ Set_OA_Setting (Current_Sem_Unit, Optimize_Alignment);
+ end if;
+
-- Loop through actual context items. This is done in two passes:
-- a) The first pass analyzes non-limited with-clauses and also any
@@ -1305,14 +1316,12 @@ package body Sem_Ch10 is
if not Implicit_With (Item) then
- -- Check compilation unit containing the limited-with clause
+ -- Verify that the illegal contexts given in 10.1.2 (18/2)
+ -- are properly rejected, including renaming declarations.
if not Nkind_In (Ukind, N_Package_Declaration,
- N_Subprogram_Declaration,
- N_Package_Renaming_Declaration,
- N_Subprogram_Renaming_Declaration)
+ N_Subprogram_Declaration)
and then Ukind not in N_Generic_Declaration
- and then Ukind not in N_Generic_Renaming_Declaration
and then Ukind not in N_Generic_Instantiation
then
Error_Msg_N ("limited with_clause not allowed here", Item);
@@ -2221,12 +2230,21 @@ package body Sem_Ch10 is
Cunit_Boolean_Restrictions_Save;
begin
+ U := Unit (Library_Unit (N));
+
+ -- Several actions are skipped for dummy packages (those supplied for
+ -- with's where no matching file could be found). Such packages are
+ -- identified by the Sloc value being set to No_Location.
+
if Limited_Present (N) then
-- Ada 2005 (AI-50217): Build visibility structures but do not
-- analyze the unit.
- Build_Limited_Views (N);
+ if Sloc (U) /= No_Location then
+ Build_Limited_Views (N);
+ end if;
+
return;
end if;
@@ -2256,13 +2274,8 @@ package body Sem_Ch10 is
Semantics (Library_Unit (N));
end if;
- U := Unit (Library_Unit (N));
Intunit := Is_Internal_File_Name (Unit_File_Name (Current_Sem_Unit));
- -- Following checks are skipped for dummy packages (those supplied for
- -- with's where no matching file could be found). Such packages are
- -- identified by the Sloc value being set to No_Location
-
if Sloc (U) /= No_Location then
-- Check restrictions, except that we skip the check if this is an
@@ -2529,6 +2542,7 @@ package body Sem_Ch10 is
if Nkind (Item) = N_With_Clause
and then not Implicit_With (Item)
+ and then not Limited_Present (Item)
and then Is_Private_Descendant (Entity (Name (Item)))
then
Priv_Child := Entity (Name (Item));
@@ -3166,7 +3180,11 @@ package body Sem_Ch10 is
-- Check that if a limited_with clause of a given compilation_unit
-- mentions a descendant of a private child of some library unit,
-- then the given compilation_unit shall be the declaration of a
- -- private descendant of that library unit.
+ -- private descendant of that library unit, or a public descendant
+ -- of such. The code is analogous to that of Check_Private_Child_Unit
+ -- but we cannot use entities on the limited with_clauses because
+ -- their units have not been analyzed, so we have to climb the tree
+ -- of ancestors looking for private keywords.
procedure Expand_Limited_With_Clause
(Comp_Unit : Node_Id;
@@ -3277,11 +3295,12 @@ package body Sem_Ch10 is
procedure Check_Private_Limited_Withed_Unit (Item : Node_Id) is
Curr_Parent : Node_Id;
Child_Parent : Node_Id;
+ Curr_Private : Boolean;
begin
-- Compilation unit of the parent of the withed library unit
- Child_Parent := Parent_Spec (Unit (Library_Unit (Item)));
+ Child_Parent := Library_Unit (Item);
-- If the child unit is a public child, then locate its nearest
-- private ancestor, if any; Child_Parent will then be set to
@@ -3297,18 +3316,21 @@ package body Sem_Ch10 is
if No (Child_Parent) then
return;
end if;
-
- Child_Parent := Parent_Spec (Unit (Child_Parent));
end if;
+ Child_Parent := Parent_Spec (Unit (Child_Parent));
+
-- Traverse all the ancestors of the current compilation
-- unit to check if it is a descendant of named library unit.
Curr_Parent := Parent (Item);
+ Curr_Private := Private_Present (Curr_Parent);
+
while Present (Parent_Spec (Unit (Curr_Parent)))
and then Curr_Parent /= Child_Parent
loop
Curr_Parent := Parent_Spec (Unit (Curr_Parent));
+ Curr_Private := Curr_Private or else Private_Present (Curr_Parent);
end loop;
if Curr_Parent /= Child_Parent then
@@ -3318,12 +3340,18 @@ package body Sem_Ch10 is
("\current unit must also have parent&!",
Item, Defining_Unit_Name (Specification (Unit (Child_Parent))));
- elsif not Private_Present (Parent (Item))
- and then not Private_Present (Item)
- and then not Nkind_In (Unit (Parent (Item)), N_Package_Body,
+ elsif Private_Present (Parent (Item))
+ or else Curr_Private
+ or else Private_Present (Item)
+ or else Nkind_In (Unit (Parent (Item)), N_Package_Body,
N_Subprogram_Body,
N_Subunit)
then
+ -- Current unit is private, of descendant of a private unit.
+
+ null;
+
+ else
Error_Msg_NE
("current unit must also be private descendant of&",
Item, Defining_Unit_Name (Specification (Unit (Child_Parent))));
@@ -3722,16 +3750,20 @@ package body Sem_Ch10 is
Item := First (Context_Items (N));
while Present (Item) loop
- -- Do not install private_with_clauses if the unit is a package
- -- declaration, unless it is itself a private child unit.
+ -- Do not install private_with_clauses declaration, unless
+ -- unit is itself a private child unit, or is a body.
+ -- Note that for a subprogram body the private_with_clause does
+ -- not take effect until after the specification.
- if Nkind (Item) = N_With_Clause
- and then not Implicit_With (Item)
- and then not Limited_Present (Item)
- and then
- (not Private_Present (Item)
- or else Nkind (Unit (N)) /= N_Package_Declaration
- or else Private_Present (N))
+ if Nkind (Item) /= N_With_Clause
+ or else Implicit_With (Item)
+ or else Limited_Present (Item)
+ then
+ null;
+
+ elsif not Private_Present (Item)
+ or else Private_Present (N)
+ or else Nkind (Unit (N)) = N_Package_Body
then
Id := Entity (Name (Item));
@@ -3792,15 +3824,26 @@ package body Sem_Ch10 is
end loop;
end;
end if;
+
+ -- If the item is a private with-clause on a child unit, the parent
+ -- may have been installed already, but the child unit must remain
+ -- invisible until installed in a private part or body.
+
+ elsif Private_Present (Item) then
+ Id := Entity (Name (Item));
+
+ if Is_Child_Unit (Id) then
+ Set_Is_Visible_Child_Unit (Id, False);
+ end if;
end if;
Next (Item);
end loop;
end Install_Siblings;
- -------------------------------
- -- Install_Limited_With_Unit --
- -------------------------------
+ ---------------------------------
+ -- Install_Limited_Withed_Unit --
+ ---------------------------------
procedure Install_Limited_Withed_Unit (N : Node_Id) is
P_Unit : constant Entity_Id := Unit (Library_Unit (N));
@@ -3810,6 +3853,14 @@ package body Sem_Ch10 is
Lim_Header : Entity_Id;
Lim_Typ : Entity_Id;
+ procedure Check_Body_Required;
+ -- A unit mentioned in a limited with_clause may not be mentioned in
+ -- a regular with_clause, but must still be included in the current
+ -- partition. We need to determine whether the unit needs a body, so
+ -- that the binder can determine the name of the file to be compiled.
+ -- Checking whether a unit needs a body can be done without semantic
+ -- analysis, by examining the nature of the declarations in the package.
+
function Has_Limited_With_Clause
(C_Unit : Entity_Id;
Pack : Entity_Id) return Boolean;
@@ -3828,6 +3879,157 @@ package body Sem_Ch10 is
-- Check if some package installed though normal with-clauses has a
-- renaming declaration of package P. AARM 10.1.2(21/2).
+ -------------------------
+ -- Check_Body_Required --
+ -------------------------
+
+ -- ??? misses pragma Import on subprograms
+ -- ??? misses pragma Import on renamed subprograms
+
+ procedure Check_Body_Required is
+ PA : constant List_Id :=
+ Pragmas_After (Aux_Decls_Node (Parent (P_Unit)));
+
+ procedure Check_Declarations (Spec : Node_Id);
+ -- Recursive procedure that does the work and checks nested packages
+
+ ------------------------
+ -- Check_Declarations --
+ ------------------------
+
+ procedure Check_Declarations (Spec : Node_Id) is
+ Decl : Node_Id;
+ Incomplete_Decls : constant Elist_Id := New_Elmt_List;
+
+ begin
+ -- Search for Elaborate Body pragma
+
+ Decl := First (Visible_Declarations (Spec));
+ while Present (Decl)
+ and then Nkind (Decl) = N_Pragma
+ loop
+ if Get_Pragma_Id (Decl) = Pragma_Elaborate_Body then
+ Set_Body_Required (Library_Unit (N));
+ return;
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ -- Look for declarations that require the presence of a body
+
+ while Present (Decl) loop
+
+ -- Subprogram that comes from source means body required
+ -- This is where a test for Import is missing ???
+
+ if Comes_From_Source (Decl)
+ and then (Nkind_In (Decl, N_Subprogram_Declaration,
+ N_Generic_Subprogram_Declaration))
+ then
+ Set_Body_Required (Library_Unit (N));
+ return;
+
+ -- Package declaration of generic package declaration. We need
+ -- to recursively examine nested declarations.
+
+ elsif Nkind_In (Decl, N_Package_Declaration,
+ N_Generic_Package_Declaration)
+ then
+ Check_Declarations (Specification (Decl));
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ -- Same set of tests for private part. In addition to subprograms
+ -- detect the presence of Taft Amendment types (incomplete types
+ -- completed in the body).
+
+ Decl := First (Private_Declarations (Spec));
+ while Present (Decl) loop
+ if Comes_From_Source (Decl)
+ and then (Nkind_In (Decl, N_Subprogram_Declaration,
+ N_Generic_Subprogram_Declaration))
+ then
+ Set_Body_Required (Library_Unit (N));
+
+ elsif Nkind_In (Decl, N_Package_Declaration,
+ N_Generic_Package_Declaration)
+ then
+ Check_Declarations (Specification (Decl));
+
+ -- Collect incomplete type declarations for separate pass
+
+ elsif Nkind (Decl) = N_Incomplete_Type_Declaration then
+ Append_Elmt (Decl, Incomplete_Decls);
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ -- Now check incomplete declarations to locate Taft amendment
+ -- types. This can be done by examing the defining identifiers
+ -- of type declarations without real semantic analysis.
+
+ declare
+ Inc : Elmt_Id;
+
+ begin
+ Inc := First_Elmt (Incomplete_Decls);
+ while Present (Inc) loop
+ Decl := Next (Node (Inc));
+ while Present (Decl) loop
+ if Nkind (Decl) = N_Full_Type_Declaration
+ and then Chars (Defining_Identifier (Decl)) =
+ Chars (Defining_Identifier (Node (Inc)))
+ then
+ exit;
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ -- If no completion, this is a TAT, and a body is needed
+
+ if No (Decl) then
+ Set_Body_Required (Library_Unit (N));
+ return;
+ end if;
+
+ Next_Elmt (Inc);
+ end loop;
+ end;
+ end Check_Declarations;
+
+ -- Start of processing for Check_Body_Required
+
+ begin
+ -- If this is an imported package (Java and CIL usage) no body is
+ -- needed. Scan list of pragmas that may follow a compilation unit
+ -- to look for a relevant pragma Import.
+
+ if Present (PA) then
+ declare
+ Prag : Node_Id;
+
+ begin
+ Prag := First (PA);
+ while Present (Prag) loop
+ if Nkind (Prag) = N_Pragma
+ and then Get_Pragma_Id (Prag) = Pragma_Import
+ then
+ return;
+ end if;
+
+ Next (Prag);
+ end loop;
+ end;
+ end if;
+
+ Check_Declarations (Specification (P_Unit));
+ end Check_Body_Required;
+
-----------------------------
-- Has_Limited_With_Clause --
-----------------------------
@@ -4017,9 +4219,12 @@ package body Sem_Ch10 is
-- In case of limited with_clause on subprograms, generics, instances,
-- or renamings, the corresponding error was previously posted and we
- -- have nothing to do here.
+ -- have nothing to do here. If the file is missing altogether, it has
+ -- no source location.
- if Nkind (P_Unit) /= N_Package_Declaration then
+ if Nkind (P_Unit) /= N_Package_Declaration
+ or else Sloc (P_Unit) = No_Location
+ then
return;
end if;
@@ -4105,39 +4310,11 @@ package body Sem_Ch10 is
-- view of X supersedes its limited view.
if Analyzed (P_Unit)
- and then (Is_Immediately_Visible (P)
- or else (Is_Child_Package
- and then Is_Visible_Child_Unit (P)))
+ and then
+ (Is_Immediately_Visible (P)
+ or else
+ (Is_Child_Package and then Is_Visible_Child_Unit (P)))
then
- -- Ada 2005 (AI-262): Install the private declarations of P
-
- if Private_Present (N)
- and then not In_Private_Part (P)
- then
- declare
- Id : Entity_Id;
-
- begin
- Id := First_Private_Entity (P);
- while Present (Id) loop
- if not Is_Internal (Id)
- and then not Is_Child_Unit (Id)
- then
- if not In_Chain (Id) then
- Set_Homonym (Id, Current_Entity (Id));
- Set_Current_Entity (Id);
- end if;
-
- Set_Is_Immediately_Visible (Id);
- end if;
-
- Next_Entity (Id);
- end loop;
-
- Set_In_Private_Part (P);
- end;
- end if;
-
return;
end if;
@@ -4296,6 +4473,13 @@ package body Sem_Ch10 is
Set_Is_Immediately_Visible (P);
Set_Limited_View_Installed (N);
+ -- If unit has not been analyzed in some previous context, check
+ -- (imperfectly ???) whether it might need a body.
+
+ if not Analyzed (P_Unit) then
+ Check_Body_Required;
+ end if;
+
-- If the package in the limited_with clause is a child unit, the
-- clause is unanalyzed and appears as a selected component. Recast
-- it as an expanded name so that the entity can be properly set. Use
@@ -4674,12 +4858,24 @@ package body Sem_Ch10 is
-- Build corresponding class_wide type, if not previously done
- -- Warning: The class-wide entity is shared by the limited-view
+ -- Note: The class-wide entity is shared by the limited-view
-- and the full-view.
if No (Class_Wide_Type (T)) then
CW := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+ -- Set parent to be the same as the parent of the tagged type.
+ -- We need a parent field set, and it is supposed to point to
+ -- the declaration of the type. The tagged type declaration
+ -- essentially declares two separate types, the tagged type
+ -- itself and the corresponding class-wide type, so it is
+ -- reasonable for the parent fields to point to the declaration
+ -- in both cases.
+
+ Set_Parent (CW, Parent (T));
+
+ -- Set remaining fields of classwide type
+
Set_Ekind (CW, E_Class_Wide_Type);
Set_Etype (CW, T);
Set_Scope (CW, Scop);
@@ -4691,6 +4887,8 @@ package body Sem_Ch10 is
Set_Equivalent_Type (CW, Empty);
Set_From_With_Type (CW, From_With_Type (T));
+ -- Link type to its class-wide type
+
Set_Class_Wide_Type (T, CW);
end if;
end Decorate_Tagged_Type;
@@ -4807,12 +5005,19 @@ package body Sem_Ch10 is
Set_Non_Limited_View (Lim_Typ, Comp_Typ);
elsif Nkind_In (Decl, N_Private_Type_Declaration,
- N_Incomplete_Type_Declaration)
+ N_Incomplete_Type_Declaration,
+ N_Task_Type_Declaration,
+ N_Protected_Type_Declaration)
then
Comp_Typ := Defining_Identifier (Decl);
+ Is_Tagged :=
+ Nkind_In (Decl, N_Private_Type_Declaration,
+ N_Incomplete_Type_Declaration)
+ and then Tagged_Present (Decl);
+
if not Analyzed_Unit then
- if Tagged_Present (Decl) then
+ if Is_Tagged then
Decorate_Tagged_Type (Sloc (Decl), Comp_Typ, Scope);
else
Decorate_Incomplete_Type (Comp_Typ, Scope);
@@ -4828,7 +5033,7 @@ package body Sem_Ch10 is
Set_Parent (Lim_Typ, Parent (Comp_Typ));
Set_From_With_Type (Lim_Typ);
- if Tagged_Present (Decl) then
+ if Is_Tagged then
Decorate_Tagged_Type (Sloc (Decl), Lim_Typ, Scope);
else
Decorate_Incomplete_Type (Lim_Typ, Scope);
@@ -4902,13 +5107,11 @@ package body Sem_Ch10 is
begin
pragma Assert (Limited_Present (N));
- -- A library_item mentioned in a limited_with_clause shall
- -- be a package_declaration, not a subprogram_declaration,
- -- generic_declaration, generic_instantiation, or
- -- package_renaming_declaration
+ -- A library_item mentioned in a limited_with_clause is a package
+ -- declaration, not a subprogram declaration, generic declaration,
+ -- generic instantiation, or package renaming declaration.
case Nkind (Unit (Library_Unit (N))) is
-
when N_Package_Declaration =>
null;