===================================================================
@@ -575,6 +575,64 @@
if No (Init_Call) and then Present (Expression (Parent (Def_Id))) then
Set_Expression (Parent (Def_Id), Empty);
end if;
+ elsif Ekind (Def_Id) = E_Exception
+ and then Convention (Def_Id) = Convention_CPP
+ then
+
+ -- Import a C++ convention
+
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Exdata : List_Id;
+ Lang_Char : Node_Id;
+ Foreign_Data : Node_Id;
+ Rtti_Name : constant Node_Id := Arg3 (N);
+ Dum : constant Entity_Id := Make_Temporary (Loc, 'D');
+
+ begin
+ Exdata := Component_Associations (Expression (Parent (Def_Id)));
+
+ Lang_Char := Next (First (Exdata));
+
+ -- Change the one-character language designator to 'C'
+
+ Rewrite (Expression (Lang_Char),
+ Make_Character_Literal (Loc,
+ Chars => Name_uC,
+ Char_Literal_Value =>
+ UI_From_Int (Character'Pos ('C'))));
+ Analyze (Expression (Lang_Char));
+
+ -- Change the value of Foreign_Data
+
+ Foreign_Data := Next (Next (Next (Next (Lang_Char))));
+
+ Insert_Actions (Def_Id, New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Dum,
+ Object_Definition =>
+ New_Occurrence_Of (Standard_Character, Loc)),
+
+ Make_Pragma (Loc,
+ Chars => Name_Import,
+ Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Loc,
+ Expression => Make_Identifier (Loc, Name_Ada)),
+
+ Make_Pragma_Argument_Association (Loc,
+ Expression => Make_Identifier (Loc, Chars (Dum))),
+
+ Make_Pragma_Argument_Association (Loc,
+ Chars => Name_Link_Name,
+ Expression => Relocate_Node (Rtti_Name))))));
+
+ Rewrite (Expression (Foreign_Data),
+ Unchecked_Convert_To (Standard_A_Char,
+ Make_Attribute_Reference (Loc,
+ Prefix => Make_Identifier (Loc, Chars (Dum)),
+ Attribute_Name => Name_Address)));
+ Analyze (Expression (Foreign_Data));
+ end;
end if;
end Expand_Pragma_Import_Or_Interface;
===================================================================
@@ -11963,6 +11963,7 @@
@emph{Exception_Name:} nnnnn
@emph{Message:} mmmmm
@emph{PID:} ppp
+@emph{Load address:} 0xhhhh
@emph{Call stack traceback locations:}
0xhhhh 0xhhhh 0xhhhh ... 0xhhh
@end smallexample
@@ -11984,10 +11985,12 @@
not making use of this field.
@item
-The Call stack traceback locations line and the following values
-are present only if at least one traceback location was recorded.
-The values are given in C style format, with lower case letters
-for a-f, and only as many digits present as are necessary.
+The Load address line, the Call stack traceback locations line and the
+following values are present only if at least one traceback location was
+recorded. The Load address indicates the address at which the main executable
+was loaded; this line may not be present if operating system hasn't relocated
+the main executable. The values are given in C style format, with lower case
+letters for a-f, and only as many digits present as are necessary.
@end itemize
@noindent
@@ -18874,6 +18877,19 @@
contains @samp{Foreign_Exception}. Finalization and awaiting dependent
tasks works properly when such foreign exceptions are propagated.
+It is also possible to import a C++ exception using the following syntax:
+
+@smallexample @c ada
+LOCAL_NAME : exception;
+pragma Import (Cpp,
+ [Entity =>] LOCAL_NAME,
+ [External_Name =>] static_string_EXPRESSION);
+@end smallexample
+
+@noident
+The @code{External_Name} is the name of the C++ RTTI symbol. You can then
+cover a specific C++ exception in an exception handler.
+
@node Interfacing to COBOL
@section Interfacing to COBOL
===================================================================
@@ -87,6 +87,36 @@
#define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL
#define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL
+/* Structure of a C++ exception, represented as a C structure... See
+ unwind-cxx.h for the full definition. */
+
+struct __cxa_exception
+{
+ void *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ void (*unexpectedHandler)();
+ void (*terminateHandler)();
+
+ struct __cxa_exception *nextException;
+
+ int handlerCount;
+
+#ifdef __ARM_EABI_UNWINDER__
+ struct __cxa_exception* nextPropagatingException;
+
+ int propagationCount;
+#else
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ _Unwind_Ptr catchTemp;
+ void *adjustedPtr;
+#endif
+
+ _Unwind_Exception unwindHeader;
+};
+
/* --------------------------------------------------------------
-- The DB stuff below is there for debugging purposes only. --
-------------------------------------------------------------- */
@@ -882,6 +912,22 @@
|| choice == (_Unwind_Ptr) &Foreign_Exception)
return handler;
+ /* C++ exception occurrences. */
+ if (propagated_exception->common.exception_class == CXX_EXCEPTION_CLASS
+ && Language_For (choice) == 'C')
+ {
+ void *choice_typeinfo = Foreign_Data_For (choice);
+ void *except_typeinfo =
+ (((struct __cxa_exception *)
+ ((_Unwind_Exception *)propagated_exception + 1)) - 1)->exceptionType;
+
+ /* Typeinfo are directly compared, which might not be correct if they
+ aren't merged. ??? We should call the == operator if this module is
+ compiled in C++. */
+ if (choice_typeinfo == except_typeinfo)
+ return handler;
+ }
+
return nothing;
}
===================================================================
@@ -7126,6 +7126,34 @@
Check_CPP_Type_Has_No_Defaults (Def_Id);
end if;
+ -- Import a CPP exception
+
+ elsif C = Convention_CPP
+ and then Ekind (Def_Id) = E_Exception
+ then
+ if No (Arg3) then
+ Error_Pragma_Arg
+ ("'External_'Name arguments is required for 'Cpp exception",
+ Arg3);
+ else
+ -- As only a string is allowed, Check_Arg_Is_External_Name
+ -- isn't called.
+ Check_Arg_Is_Static_Expression (Arg3, Standard_String);
+ end if;
+
+ if Present (Arg4) then
+ Error_Pragma_Arg
+ ("Link_Name argument not allowed for imported Cpp exception",
+ Arg4);
+ end if;
+
+ -- Do not call Set_Interface_Name as the name of the exception
+ -- shouldn't be modified (and in particular it shouldn't be
+ -- the External_Name). For exceptions, the External_Name is the
+ -- name of the RTTI structure.
+
+ -- ??? Emit an error if pragma Import/Export_Exception is present
+
elsif Nkind (Parent (Def_Id)) = N_Incomplete_Type_Declaration then
Check_No_Link_Name;
Check_Arg_Count (3);