aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2024-12-10 09:06:57 -0300
committerMarc Poulhiès <dkm@gcc.gnu.org>2025-01-06 10:14:49 +0100
commit2d2b018dcc4f5a822257688fb393fe0094d92d6d (patch)
treed71bb12c10da1d8c359e9402b69d5d2f8a8b1ba3 /gcc
parentf49b098e7d19ea60b450b01e4434a00e7e5ca90b (diff)
downloadgcc-2d2b018dcc4f5a822257688fb393fe0094d92d6d.zip
gcc-2d2b018dcc4f5a822257688fb393fe0094d92d6d.tar.gz
gcc-2d2b018dcc4f5a822257688fb393fe0094d92d6d.tar.bz2
ada: Reduce footprint of C++ exception interoperation support
The initial C++ base-type exception interoperation support change brought all of GNAT.CPP* along with raise-gcc, because of [__gnat_]Convert_Caught_Object. Move that private but pragma-exported function to GNAT.CPP.Std.Type_Info, so that it can rely on the C++ virtual/dispatch calls that justified the introduction of the Ada wrapper type, to avoid emulating virtual calls in C or bringing in a dependency on the C++ compiler and runtime. Drop the CharPtr package instantiation, that brought a huge amount of unnecessary code, and use string and storage primitives instead, using the strcmp builtin directly for the C string compares. Move the conversion to Ada String in Name to the wrapper interface in GNAT.CPP.Std, adjusting the private internal type to shave off a few more bytes from the only unit that raise-gcc will still need. Finally, disable heap finalization for Type_Info_Ptr, to avoid dragging in all of the finalization code. Thank to Eric Botcazou for the suggestion. gcc/ada/ChangeLog: * libgnat/g-cppexc.adb (Convert_Caught_Object): Move... * libgnat/g-cstyin.adb (Convert_Caught_Object): ... here. Use object call notation. (strcmp): New. (Char_Arr, CharPtr, Char_Pointer, To_chars_ptr): Drop. Do not import Interfaces.C.Pointers. (To_Pointer): Convert from System.Address. (Name_Starts_With_Asterisk): Rename local variable. (Name_Past_Asterisk): Rewrite with System.Address and strcmp. Import System.Storage_Elements. (Equals): Use strcmp. (Before): Fix logic error. Use strcmp. (Name): Move conversion to String... * libgnat/g-cppstd.adb (Name): ... here. Import Interfaces.C.Strings. * libgnat/g-cppstd.ads (Type_Info_Ptr): Disable heap finalization. * libgnat/g-cstyin.ads (Name): Change return type.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/libgnat/g-cppexc.adb40
-rw-r--r--gcc/ada/libgnat/g-cppstd.adb3
-rw-r--r--gcc/ada/libgnat/g-cppstd.ads4
-rw-r--r--gcc/ada/libgnat/g-cstyin.adb80
-rw-r--r--gcc/ada/libgnat/g-cstyin.ads2
5 files changed, 65 insertions, 64 deletions
diff --git a/gcc/ada/libgnat/g-cppexc.adb b/gcc/ada/libgnat/g-cppexc.adb
index 1102288..bad748f 100644
--- a/gcc/ada/libgnat/g-cppexc.adb
+++ b/gcc/ada/libgnat/g-cppexc.adb
@@ -267,44 +267,4 @@ package body GNAT.CPP_Exceptions is
end Get_Type_Info;
- function Convert_Caught_Object (Choice, Except : Type_Info_Ptr;
- Thrown : in out Address;
- Lang : Character)
- return Interfaces.C.C_bool;
- pragma Export (Cpp, Convert_Caught_Object, "__gnat_convert_caught_object");
- -- Convert the exception object at Thrown, under Lang convention,
- -- from type Except to type Choice, adjusting Thrown as needed and
- -- returning True, or returning False in case the conversion fails.
-
- ---------------------------
- -- Convert_Caught_Object --
- ---------------------------
-
- function Convert_Caught_Object (Choice, Except : Type_Info_Ptr;
- Thrown : in out Address;
- Lang : Character)
- return Interfaces.C.C_bool is
- begin
- if Equals (Choice, Except) then
- return C_bool'(True);
- end if;
-
- if Lang = 'B' then
- if Is_Pointer_P (Except) then
- declare
- Thrown_Indirect : Address;
- for Thrown_Indirect'Address use Thrown;
- begin
- Thrown := Thrown_Indirect;
- end;
- end if;
-
- if Do_Catch (Choice, Except, Thrown, 1) then
- return C_bool'(True);
- end if;
- end if;
-
- return C_bool'(False);
- end Convert_Caught_Object;
-
end GNAT.CPP_Exceptions;
diff --git a/gcc/ada/libgnat/g-cppstd.adb b/gcc/ada/libgnat/g-cppstd.adb
index 000dd47..8cb64ed 100644
--- a/gcc/ada/libgnat/g-cppstd.adb
+++ b/gcc/ada/libgnat/g-cppstd.adb
@@ -34,6 +34,7 @@
with GNAT.CPP.Std.Type_Info;
with Ada.Unchecked_Conversion;
+with Interfaces.C.Strings; use Interfaces.C.Strings;
package body GNAT.CPP.Std is
----------------------
@@ -53,7 +54,7 @@ package body GNAT.CPP.Std is
function Name (this : Type_Info_Ptr)
return String
- is (this.all.Name);
+ is (Value (this.all.Name));
---------------
-- Before ---
diff --git a/gcc/ada/libgnat/g-cppstd.ads b/gcc/ada/libgnat/g-cppstd.ads
index 63ef03e..be8907c 100644
--- a/gcc/ada/libgnat/g-cppstd.ads
+++ b/gcc/ada/libgnat/g-cppstd.ads
@@ -50,7 +50,8 @@ package GNAT.CPP.Std is
function Name (this : Type_Info_Ptr)
-- return Interfaces.C.Strings.chars_ptr;
return String;
- -- Exposed std::type_info member function.
+ -- Exposed std::type_info member function. ??? Would it ever be
+ -- desirable to get direct access to the internal chars_ptr?
function Before (this, that : Type_Info_Ptr)
-- return Interfaces.C.Extensions.bool;
@@ -89,6 +90,7 @@ private
type Type_Info_Ptr is access constant Type_Info.type_info'Class;
pragma No_Strict_Aliasing (Type_Info_Ptr);
+ pragma No_Heap_Finalization (Type_Info_Ptr);
No_Type_Info : constant Type_Info_Ptr := null;
diff --git a/gcc/ada/libgnat/g-cstyin.adb b/gcc/ada/libgnat/g-cstyin.adb
index 8036ed5..b194f7f 100644
--- a/gcc/ada/libgnat/g-cstyin.adb
+++ b/gcc/ada/libgnat/g-cstyin.adb
@@ -30,14 +30,17 @@
------------------------------------------------------------------------------
with System; use System;
+with System.Storage_Elements; use System.Storage_Elements;
with Interfaces.C; use Interfaces.C;
-with Interfaces.C.Pointers;
with Interfaces.C.Extensions; use Interfaces.C.Extensions;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Ada.Unchecked_Conversion;
package body GNAT.CPP.Std.Type_Info is
+ function strcmp (L, R : chars_ptr) return Interfaces.C.int;
+ pragma Import (Intrinsic, strcmp, "__builtin_strcmp");
+
function Name_Starts_With_Asterisk (this : access constant type_info'Class)
return Boolean;
@@ -46,35 +49,27 @@ package body GNAT.CPP.Std.Type_Info is
function To_Address is
new Ada.Unchecked_Conversion (chars_ptr, System.Address);
-
- type Char_Arr is array (Natural range <>) of aliased char;
- package CharPtr is
- new Interfaces.C.Pointers (Natural, char, Char_Arr, nul);
- type Char_Pointer is new CharPtr.Pointer;
-
function To_Pointer is
- new Ada.Unchecked_Conversion (chars_ptr, Char_Pointer);
- function To_chars_ptr is
- new Ada.Unchecked_Conversion (Char_Pointer, chars_ptr);
+ new Ada.Unchecked_Conversion (System.Address, chars_ptr);
function Name_Starts_With_Asterisk (this : access constant type_info'Class)
return Boolean is
- A : constant Address := To_Address (this.Raw_Name);
+ Addr : constant System.Address := To_Address (this.Raw_Name);
C : aliased char;
- for C'Address use A;
+ for C'Address use Addr;
begin
return C = '*';
end Name_Starts_With_Asterisk;
function Name_Past_Asterisk (this : access constant type_info'Class)
return chars_ptr is
- Addr : Char_Pointer := To_Pointer (this.Raw_Name);
+ Addr : System.Address := To_Address (this.Raw_Name);
begin
if this.Name_Starts_With_Asterisk then
- Increment (Addr);
+ Addr := Addr + Storage_Offset (1);
end if;
- return To_chars_ptr (Addr);
+ return To_Pointer (Addr);
end Name_Past_Asterisk;
------------
@@ -82,8 +77,8 @@ package body GNAT.CPP.Std.Type_Info is
------------
function Name (this : access constant type_info'Class)
- return String
- is (Value (this.Name_Past_Asterisk));
+ return chars_ptr
+ is (this.Name_Past_Asterisk);
--------------
-- Before --
@@ -92,10 +87,10 @@ package body GNAT.CPP.Std.Type_Info is
function Before (this, that : access constant type_info'Class)
return Boolean is
begin
- if this.Name_Starts_With_Asterisk
- or else that.Name_Starts_With_Asterisk
+ if not this.Name_Starts_With_Asterisk
+ or else not that.Name_Starts_With_Asterisk
then
- return this.Name < that.Name;
+ return strcmp (this.Raw_Name, that.Raw_Name) < 0;
end if;
return To_Address (this.Raw_Name) < To_Address (that.Raw_Name);
@@ -116,7 +111,50 @@ package body GNAT.CPP.Std.Type_Info is
return False;
end if;
- return this.Name = that.Name;
+ return strcmp (this.Raw_Name, that.Raw_Name) = 0;
end Equals;
+ function Convert_Caught_Object (Choice, Except : access type_info'Class;
+ Thrown : in out Address;
+ Lang : Character)
+ return Interfaces.C.C_bool;
+ pragma Export (Cpp, Convert_Caught_Object, "__gnat_convert_caught_object");
+ -- Convert the exception object at Thrown, under Lang convention,
+ -- from type Except to type Choice, adjusting Thrown as needed and
+ -- returning True, or returning False in case the conversion
+ -- fails. This is called from raise-gcc, and it is placed here
+ -- rather than in GNAT.CPP_Exceptions to avoid dragging all that
+ -- in when the program doesn't use C++ exceptions.
+
+ ---------------------------
+ -- Convert_Caught_Object --
+ ---------------------------
+
+ function Convert_Caught_Object (Choice, Except : access type_info'Class;
+ Thrown : in out Address;
+ Lang : Character)
+ return Interfaces.C.C_bool is
+ begin
+ if Choice.Equals (Except) then
+ return C_bool'(True);
+ end if;
+
+ if Lang = 'B' then
+ if Except.Is_Pointer_P then
+ declare
+ Thrown_Indirect : Address;
+ for Thrown_Indirect'Address use Thrown;
+ begin
+ Thrown := Thrown_Indirect;
+ end;
+ end if;
+
+ if Choice.Do_Catch (Except, Thrown, 1) then
+ return C_bool'(True);
+ end if;
+ end if;
+
+ return C_bool'(False);
+ end Convert_Caught_Object;
+
end GNAT.CPP.Std.Type_Info;
diff --git a/gcc/ada/libgnat/g-cstyin.ads b/gcc/ada/libgnat/g-cstyin.ads
index 06ed958..37dad45 100644
--- a/gcc/ada/libgnat/g-cstyin.ads
+++ b/gcc/ada/libgnat/g-cstyin.ads
@@ -71,7 +71,7 @@ private package GNAT.CPP.Std.Type_Info is
-- Reimplemented in Ada, using Ada types.
function Name (this : access constant type_info'Class)
-- return Interfaces.C.Strings.chars_ptr;
- return String;
+ return Interfaces.C.Strings.chars_ptr;
-- pragma Import (CPP, Name, "_ZNKSt9type_info4nameEv");
pragma Machine_Attribute (Name, "nothrow");