summaryrefslogtreecommitdiff
path: root/gcc/ada/freeze.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/freeze.adb')
-rw-r--r--gcc/ada/freeze.adb175
1 files changed, 113 insertions, 62 deletions
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 31f93985c44..5e069f4c7a4 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -134,6 +134,11 @@ package body Freeze is
-- the designated type. Otherwise freezing the access type does not freeze
-- the designated type.
+ procedure Generate_Prim_Op_References
+ (Typ : Entity_Id);
+ -- For a tagged type, generate implicit references to its primitive
+ -- operations, for source navigation.
+
procedure Process_Default_Expressions
(E : Entity_Id;
After : in out Node_Id);
@@ -2398,6 +2403,8 @@ package body Freeze is
elsif Root_Type (F_Type) = Standard_Boolean
and then Convention (F_Type) = Convention_Ada
+ and then not Has_Warnings_Off (F_Type)
+ and then not Has_Size_Clause (F_Type)
then
Error_Msg_N
("?& is an 8-bit Ada Boolean, "
@@ -2543,6 +2550,7 @@ package body Freeze is
and then Convention (R_Type) = Convention_Ada
and then not Has_Warnings_Off (E)
and then not Has_Warnings_Off (R_Type)
+ and then not Has_Size_Clause (R_Type)
then
Error_Msg_N
("?return type of & is an 8-bit "
@@ -2597,6 +2605,10 @@ package body Freeze is
--
-- type T is tagged;
-- function F (X : Boolean) return T; -- ERROR
+ -- The type must be declared in the current scope
+ -- for the use to be legal, and the full view
+ -- must be available when the construct that mentions
+ -- it is frozen.
elsif Ekind (Etype (E)) = E_Incomplete_Type
and then Is_Tagged_Type (Etype (E))
@@ -2605,7 +2617,7 @@ package body Freeze is
then
Error_Msg_N
("(Ada 2005): invalid use of tagged incomplete type",
- E);
+ E);
end if;
end if;
end;
@@ -2632,10 +2644,30 @@ package body Freeze is
-- Here for other than a subprogram or type
else
+ -- For a generic package, freeze types within, so that proper
+ -- cross-reference information is generated for tagged types.
+ -- This is the only freeze processing needed for generic packages.
+
+ if Ekind (E) = E_Generic_Package then
+ declare
+ T : Entity_Id;
+
+ begin
+ T := First_Entity (E);
+
+ while Present (T) loop
+ if Is_Type (T) then
+ Generate_Prim_Op_References (T);
+ end if;
+
+ Next_Entity (T);
+ end loop;
+ end;
+
-- If entity has a type, and it is not a generic unit, then
-- freeze it first (RM 13.14(10)).
- if Present (Etype (E))
+ elsif Present (Etype (E))
and then Ekind (E) /= E_Generic_Function
then
Freeze_And_Append (Etype (E), Loc, Result);
@@ -2661,8 +2693,16 @@ package body Freeze is
-- The check doesn't apply to imported objects, which are not
-- ever default initialized, and is why the check is deferred
-- until freezing, at which point we know if Import applies.
+ -- Deferred constants are also exempted from this test because
+ -- their completion is explicit, or through an import pragma.
- if not Is_Imported (E)
+ if Ekind (E) = E_Constant
+ and then Present (Full_View (E))
+ then
+ null;
+
+ elsif Comes_From_Source (E)
+ and then not Is_Imported (E)
and then not Has_Init_Expression (Declaration_Node (E))
and then
((Has_Non_Null_Base_Init_Proc (Etype (E))
@@ -3617,66 +3657,9 @@ package body Freeze is
end if;
end if;
- -- Generate primitive operation references for a tagged type
-
- if Is_Tagged_Type (E)
- and then not Is_Class_Wide_Type (E)
- then
- declare
- Prim_List : Elist_Id;
- Prim : Elmt_Id;
- Ent : Entity_Id;
- Aux_E : Entity_Id;
-
- begin
- -- Handle subtypes
-
- if Ekind (E) = E_Protected_Subtype
- or else Ekind (E) = E_Task_Subtype
- then
- Aux_E := Etype (E);
- else
- Aux_E := E;
- end if;
-
- -- Ada 2005 (AI-345): In case of concurrent type generate
- -- reference to the wrapper that allow us to dispatch calls
- -- through their implemented abstract interface types.
-
- -- The check for Present here is to protect against previously
- -- reported critical errors.
-
- if Is_Concurrent_Type (Aux_E)
- and then Present (Corresponding_Record_Type (Aux_E))
- then
- Prim_List := Primitive_Operations
- (Corresponding_Record_Type (Aux_E));
- else
- Prim_List := Primitive_Operations (Aux_E);
- end if;
-
- -- Loop to generate references for primitive operations
-
- if Present (Prim_List) then
- Prim := First_Elmt (Prim_List);
- while Present (Prim) loop
-
- -- If the operation is derived, get the original for
- -- cross-reference purposes (it is the original for
- -- which we want the xref, and for which the comes
- -- from source test needs to be performed).
-
- Ent := Node (Prim);
- while Present (Alias (Ent)) loop
- Ent := Alias (Ent);
- end loop;
+ -- Generate references to primitive operations for a tagged type
- Generate_Reference (E, Ent, 'p', Set_Ref => False);
- Next_Elmt (Prim);
- end loop;
- end if;
- end;
- end if;
+ Generate_Prim_Op_References (E);
-- Now that all types from which E may depend are frozen, see if the
-- size is known at compile time, if it must be unsigned, or if
@@ -5221,6 +5204,74 @@ package body Freeze is
end Is_Fully_Defined;
---------------------------------
+ -- Generate_Prim_Op_References --
+ ---------------------------------
+
+ procedure Generate_Prim_Op_References
+ (Typ : Entity_Id)
+ is
+ Base_T : Entity_Id;
+ Prim : Elmt_Id;
+ Prim_List : Elist_Id;
+ Ent : Entity_Id;
+
+ begin
+ -- Handle subtypes of synchronized types.
+
+ if Ekind (Typ) = E_Protected_Subtype
+ or else Ekind (Typ) = E_Task_Subtype
+ then
+ Base_T := Etype (Typ);
+ else
+ Base_T := Typ;
+ end if;
+
+ -- References to primitive operations are only relevant for tagged types
+
+ if not Is_Tagged_Type (Base_T)
+ or else Is_Class_Wide_Type (Base_T)
+ then
+ return;
+ end if;
+
+ -- Ada 2005 (AI-345): For synchronized types generate reference
+ -- to the wrapper that allow us to dispatch calls through their
+ -- implemented abstract interface types.
+
+ -- The check for Present here is to protect against previously
+ -- reported critical errors.
+
+ if Is_Concurrent_Type (Base_T)
+ and then Present (Corresponding_Record_Type (Base_T))
+ then
+ Prim_List := Primitive_Operations
+ (Corresponding_Record_Type (Base_T));
+ else
+ Prim_List := Primitive_Operations (Base_T);
+ end if;
+
+ if No (Prim_List) then
+ return;
+ end if;
+
+ Prim := First_Elmt (Prim_List);
+ while Present (Prim) loop
+
+ -- If the operation is derived, get the original for cross-reference
+ -- reference purposes (it is the original for which we want the xref
+ -- and for which the comes_from_source test must be performed).
+
+ Ent := Node (Prim);
+ while Present (Alias (Ent)) loop
+ Ent := Alias (Ent);
+ end loop;
+
+ Generate_Reference (Typ, Ent, 'p', Set_Ref => False);
+ Next_Elmt (Prim);
+ end loop;
+ end Generate_Prim_Op_References;
+
+ ---------------------------------
-- Process_Default_Expressions --
---------------------------------