summaryrefslogtreecommitdiff
path: root/gcc/ada/bindgen.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/bindgen.adb')
-rw-r--r--gcc/ada/bindgen.adb197
1 files changed, 136 insertions, 61 deletions
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index 58636541215..41256aebc66 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -1662,38 +1662,84 @@ package body Bindgen is
Uspec : Unit_Record;
Unum : Unit_Id;
+ procedure Gen_Header;
+ -- Generate the header of the finalization routine
+
+ procedure Gen_Header is
+ begin
+ WBI (" procedure finalize_library is");
+
+ -- The following flag is used to check for library-level
+ -- exceptions raised during finalization. The symbol comes
+ -- from System.Soft_Links. VM targets use regular Ada to
+ -- reference the entity.
+
+ if VM_Target = No_VM then
+ WBI (" LE_Set : Boolean;");
+
+ Set_String (" pragma Import (Ada, LE_Set, ");
+ Set_String ("""__gnat_library_exception_set"");");
+ Write_Statement_Buffer;
+ end if;
+
+ WBI (" begin");
+ end Gen_Header;
+
begin
for E in reverse Elab_Order.First .. Elab_Order.Last loop
Unum := Elab_Order.Table (E);
U := Units.Table (Unum);
+ -- Dealing with package bodies is a little complicated. In such
+ -- cases we must retrieve the package spec since it contains the
+ -- spec of the body finalizer.
+
+ if U.Utype = Is_Body then
+ Unum := Unum + 1;
+ Uspec := Units.Table (Unum);
+ else
+ Uspec := U;
+ end if;
+
+ Get_Name_String (Uspec.Uname);
+
-- We are only interested in non-generic packages
- if U.Unit_Kind = 'p'
- and then U.Has_Finalizer
- and then not U.Is_Generic
- and then not U.SAL_Interface
- and then not U.No_Elab
- then
- if not Lib_Final_Built then
- Lib_Final_Built := True;
+ if U.Unit_Kind /= 'p' or else U.Is_Generic then
+ null;
- WBI (" procedure finalize_library is");
+ -- That aren't an interface to a stand alone library
- -- The following flag is used to check for library-level
- -- exceptions raised during finalization. The symbol comes
- -- from System.Soft_Links. VM targets use regular Ada to
- -- reference the entity.
+ elsif U.SAL_Interface then
+ null;
- if VM_Target = No_VM then
- WBI (" LE_Set : Boolean;");
+ -- Case of no finalization
- Set_String (" pragma Import (Ada, LE_Set, ");
- Set_String ("""__gnat_library_exception_set"");");
- Write_Statement_Buffer;
+ elsif not U.Has_Finalizer then
+
+ -- The only case in which we have to do something is if this
+ -- is a body, with a separate spec, where the separate spec
+ -- has a finalizer. In that case, this is where we decrement
+ -- the elaboration entity.
+
+ if U.Utype = Is_Body and then Uspec.Has_Finalizer then
+ if not Lib_Final_Built then
+ Gen_Header;
+ Lib_Final_Built := True;
end if;
- WBI (" begin");
+ Set_String (" E");
+ Set_Unit_Number (Unum);
+ Set_String (" := E");
+ Set_Unit_Number (Unum);
+ Set_String (" - 1;");
+ Write_Statement_Buffer;
+ end if;
+
+ else
+ if not Lib_Final_Built then
+ Gen_Header;
+ Lib_Final_Built := True;
end if;
-- Generate:
@@ -1732,19 +1778,6 @@ package body Bindgen is
Set_Int (Count);
Set_String (", """);
- -- Dealing with package bodies is a little complicated. In such
- -- cases we must retrieve the package spec since it contains the
- -- spec of the body finalizer.
-
- if U.Utype = Is_Body then
- Unum := Unum + 1;
- Uspec := Units.Table (Unum);
- else
- Uspec := U;
- end if;
-
- Get_Name_String (Uspec.Uname);
-
-- Perform name construction
-- .NET xx.yy_pkg.xx__yy__finalize
@@ -1798,13 +1831,19 @@ package body Bindgen is
-- F<Count>;
-- end;
+ -- The uname_E decrement is skipped if this is a separate spec,
+ -- since it will be done when we process the body.
+
WBI (" begin");
- Set_String (" E");
- Set_Unit_Number (Unum);
- Set_String (" := E");
- Set_Unit_Number (Unum);
- Set_String (" - 1;");
- Write_Statement_Buffer;
+
+ if U.Utype /= Is_Spec then
+ Set_String (" E");
+ Set_Unit_Number (Unum);
+ Set_String (" := E");
+ Set_Unit_Number (Unum);
+ Set_String (" - 1;");
+ Write_Statement_Buffer;
+ end if;
if Interface_Library_Unit or not Bind_Main_Program then
Set_String (" if E");
@@ -1884,37 +1923,68 @@ package body Bindgen is
Uspec : Unit_Record;
Unum : Unit_Id;
+ procedure Gen_Header;
+ -- Generate the header of the finalization routine
+
+ procedure Gen_Header is
+ begin
+ WBI ("static void finalize_library(void) {");
+ end Gen_Header;
+
begin
for E in reverse Elab_Order.First .. Elab_Order.Last loop
Unum := Elab_Order.Table (E);
U := Units.Table (Unum);
+ -- Dealing with package bodies is a little complicated. In such
+ -- cases we must retrieve the package spec since it contains the
+ -- spec of the body finalizer.
+
+ if U.Utype = Is_Body then
+ Unum := Unum + 1;
+ Uspec := Units.Table (Unum);
+ else
+ Uspec := U;
+ end if;
+
+ Get_Name_String (Uspec.Uname);
+
-- We are only interested in non-generic packages
- if U.Unit_Kind = 'p'
- and then U.Has_Finalizer
- and then not U.Is_Generic
- and then not U.SAL_Interface
- and then not U.No_Elab
- then
- if not Lib_Final_Built then
- Lib_Final_Built := True;
+ if U.Unit_Kind /= 'p' or else U.Is_Generic then
+ null;
- WBI ("static void finalize_library(void) {");
- end if;
+ -- That aren't an interface to a stand alone library
- -- Dealing with package bodies is a little complicated. In such
- -- cases we must retrieve the package spec since it contains the
- -- spec of the body finalizer.
+ elsif U.SAL_Interface then
+ null;
- if U.Utype = Is_Body then
- Unum := Unum + 1;
- Uspec := Units.Table (Unum);
- else
- Uspec := U;
+ -- Case of no finalization
+
+ elsif not U.Has_Finalizer then
+
+ -- The only case in which we have to do something is if this
+ -- is a body, with a separate spec, where the separate spec
+ -- has a finalizer. In that case, this is where we decrement
+ -- the elaboration entity.
+
+ if U.Utype = Is_Body and then Uspec.Has_Finalizer then
+ if not Lib_Final_Built then
+ Gen_Header;
+ Lib_Final_Built := True;
+ end if;
+
+ Set_String (" ");
+ Set_Unit_Name;
+ Set_String ("_E--;");
+ Write_Statement_Buffer;
end if;
- Get_Name_String (Uspec.Uname);
+ else
+ if not Lib_Final_Built then
+ Gen_Header;
+ Lib_Final_Built := True;
+ end if;
-- If binding a library or if there is a non-Ada main subprogram
-- then we generate:
@@ -1928,10 +1998,15 @@ package body Bindgen is
-- uname_E--;
-- uname__finalize_[spec|body] ();
- Set_String (" ");
- Set_Unit_Name;
- Set_String ("_E--;");
- Write_Statement_Buffer;
+ -- The uname_E decrement is skipped if this is a separate spec,
+ -- since it will be done when we process the body.
+
+ if U.Utype /= Is_Spec then
+ Set_String (" ");
+ Set_Unit_Name;
+ Set_String ("_E--;");
+ Write_Statement_Buffer;
+ end if;
if Interface_Library_Unit or not Bind_Main_Program then
Set_String (" if (");