===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1992-2016, 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- --
@@ -68,9 +68,12 @@
function Get_Code_Or_Source_Unit
(S : Source_Ptr;
- Unwind_Instances : Boolean) return Unit_Number_Type;
- -- Common code for Get_Code_Unit (get unit of instantiation for location)
- -- and Get_Source_Unit (get unit of template for location).
+ Unwind_Instances : Boolean;
+ Unwind_Subunits : Boolean) return Unit_Number_Type;
+ -- Common code for Get_Code_Unit (get unit of instantiation for
+ -- location) Get_Source_Unit (get unit of template for location) and
+ -- Get_Top_Level_Code_Unit (same as Get_Code_Unit but not stopping at
+ -- subunits).
--------------------------------------------
-- Access Functions for Unit Table Fields --
@@ -573,7 +576,8 @@
function Get_Code_Or_Source_Unit
(S : Source_Ptr;
- Unwind_Instances : Boolean) return Unit_Number_Type
+ Unwind_Instances : Boolean;
+ Unwind_Subunits : Boolean) return Unit_Number_Type
is
begin
-- Search table unless we have No_Location, which can happen if the
@@ -584,6 +588,7 @@
declare
Source_File : Source_File_Index;
Source_Unit : Unit_Number_Type;
+ Unit_Node : Node_Id;
begin
Source_File := Get_Source_File_Index (S);
@@ -596,6 +601,21 @@
Source_Unit := Unit (Source_File);
+ if Unwind_Subunits then
+ Unit_Node := Unit (Cunit (Source_Unit));
+
+ while Nkind (Unit_Node) = N_Subunit
+ and then Present (Corresponding_Stub (Unit_Node))
+ loop
+ Source_Unit :=
+ Get_Code_Or_Source_Unit
+ (Sloc (Corresponding_Stub (Unit_Node)),
+ Unwind_Instances => Unwind_Instances,
+ Unwind_Subunits => Unwind_Subunits);
+ Unit_Node := Unit (Cunit (Source_Unit));
+ end loop;
+ end if;
+
if Source_Unit /= No_Unit then
return Source_Unit;
end if;
@@ -616,7 +636,7 @@
function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type is
begin
return Get_Code_Or_Source_Unit (Top_Level_Location (S),
- Unwind_Instances => False);
+ Unwind_Instances => False, Unwind_Subunits => False);
end Get_Code_Unit;
function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
@@ -691,7 +711,8 @@
function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type is
begin
- return Get_Code_Or_Source_Unit (S, Unwind_Instances => True);
+ return Get_Code_Or_Source_Unit (S,
+ Unwind_Instances => True, Unwind_Subunits => False);
end Get_Source_Unit;
function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
@@ -699,6 +720,22 @@
return Get_Source_Unit (Sloc (N));
end Get_Source_Unit;
+ -----------------------------
+ -- Get_Top_Level_Code_Unit --
+ -----------------------------
+
+ function Get_Top_Level_Code_Unit (S : Source_Ptr) return Unit_Number_Type is
+ begin
+ return Get_Code_Or_Source_Unit (Top_Level_Location (S),
+ Unwind_Instances => False, Unwind_Subunits => True);
+ end Get_Top_Level_Code_Unit;
+
+ function Get_Top_Level_Code_Unit
+ (N : Node_Or_Entity_Id) return Unit_Number_Type is
+ begin
+ return Get_Top_Level_Code_Unit (Sloc (N));
+ end Get_Top_Level_Code_Unit;
+
--------------------------------
-- In_Extended_Main_Code_Unit --
--------------------------------
===================================================================
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
+-- Copyright (C) 1992-2016, 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- --
@@ -541,6 +541,14 @@
-- template, so it returns the unit number containing the code that
-- corresponds to the node N, or the source location S.
+ function Get_Top_Level_Code_Unit
+ (N : Node_Or_Entity_Id) return Unit_Number_Type;
+ pragma Inline (Get_Code_Unit);
+ function Get_Top_Level_Code_Unit (S : Source_Ptr) return Unit_Number_Type;
+ -- This is like Get_Code_Unit, except that in the case of subunits, it
+ -- returns the top-level unit to which the subunit belongs instead of
+ -- the subunit.
+
function In_Extended_Main_Code_Unit
(N : Node_Or_Entity_Id) return Boolean;
-- Return True if the node is in the generated code of the extended main
===================================================================
@@ -150,6 +150,15 @@
return;
end if;
+ -- Subunits are traversed as part of the top-level unit to which they
+ -- belong.
+
+ if Present (Cunit (Ubody))
+ and then Nkind (Unit (Cunit (Ubody))) = N_Subunit
+ then
+ return;
+ end if;
+
From := SPARK_Scope_Table.Last + 1;
-- Unit might not have an associated compilation unit, as seen in code
@@ -610,6 +619,8 @@
-- Both entities must be equal at this point
pragma Assert (T1.Key.Ent = T2.Key.Ent);
+ pragma Assert (T1.Key.Ent_Scope = T2.Key.Ent_Scope);
+ pragma Assert (T1.Ent_Scope_File = T2.Ent_Scope_File);
-- Fourth test: if reference is in same unit as entity definition,
-- sort first.
@@ -1210,18 +1221,20 @@
Deref.Loc := Loc;
Deref.Typ := Typ;
- -- It is as if the special "Heap" was defined in every scope where
- -- it is referenced.
+ -- It is as if the special "Heap" was defined in the main unit,
+ -- in the scope of the entity for the main unit. This single
+ -- definition point is required to ensure that sorting cross
+ -- references works for "Heap" references as well.
- Deref.Eun := Get_Code_Unit (Loc);
- Deref.Lun := Get_Code_Unit (Loc);
+ Deref.Eun := Main_Unit;
+ Deref.Lun := Get_Top_Level_Code_Unit (Loc);
Deref.Ref_Scope := Ref_Scope;
- Deref.Ent_Scope := Ref_Scope;
+ Deref.Ent_Scope := Cunit_Entity (Main_Unit);
Deref_Entry.Def := No_Location;
- Deref_Entry.Ent_Scope_File := Get_Code_Unit (N);
+ Deref_Entry.Ent_Scope_File := Main_Unit;
end;
end if;
end Generate_Dereference;
===================================================================
@@ -1075,11 +1075,11 @@
((Ent => Ent,
Loc => Ref,
Typ => Actual_Typ,
- Eun => Get_Code_Unit (Def),
- Lun => Get_Code_Unit (Ref),
+ Eun => Get_Top_Level_Code_Unit (Def),
+ Lun => Get_Top_Level_Code_Unit (Ref),
Ref_Scope => Ref_Scope,
Ent_Scope => Ent_Scope),
- Ent_Scope_File => Get_Code_Unit (Ent));
+ Ent_Scope_File => Get_Top_Level_Code_Unit (Ent));
else
Ref := Original_Location (Sloc (Nod));