procedure Gen_Adainit_Ada;
-- Generates the Adainit procedure (Ada code case)
- procedure Gen_Adainit_C;
- -- Generates the Adainit procedure (C code case)
-
procedure Gen_Adafinal_Ada;
-- Generate the Adafinal procedure (Ada code case)
- procedure Gen_Adafinal_C;
- -- Generate the Adafinal procedure (C code case)
-
procedure Gen_Elab_Externals_Ada;
-- Generate sequence of external declarations for elaboration (Ada)
- procedure Gen_Elab_Externals_C;
- -- Generate sequence of external declarations for elaboration (C)
-
procedure Gen_Elab_Calls_Ada;
-- Generate sequence of elaboration calls (Ada code case)
- procedure Gen_Elab_Calls_C;
- -- Generate sequence of elaboration calls (C code case)
-
procedure Gen_Elab_Order_Ada;
-- Generate comments showing elaboration order chosen (Ada code case)
- procedure Gen_Elab_Order_C;
- -- Generate comments showing elaboration order chosen (C code case)
-
- procedure Gen_Elab_Defs_C;
- -- Generate sequence of definitions for elaboration routines (C code case)
-
procedure Gen_Finalize_Library_Ada;
-- Generate a sequence of finalization calls to elaborated packages (Ada)
- procedure Gen_Finalize_Library_C;
- -- Generate a sequence of finalization calls to elaborated packages (C)
-
- procedure Gen_Finalize_Library_Defs_C;
- -- Generate a sequence of defininitions for package finalizers (C case)
-
procedure Gen_CodePeer_Wrapper;
-- For CodePeer, generate wrapper which calls user-defined main subprogram
procedure Gen_Main_Ada;
-- Generate procedure main (Ada code case)
- procedure Gen_Main_C;
- -- Generate main() procedure (C code case)
-
procedure Gen_Object_Files_Options;
-- Output comments containing a list of the full names of the object
-- files to be linked and the list of linker options supplied by
procedure Gen_Output_File_Ada (Filename : String);
-- Generate output file (Ada code case)
- procedure Gen_Output_File_C (Filename : String);
- -- Generate output file (C code case)
-
procedure Gen_Restrictions_Ada;
-- Generate initialization of restrictions variable (Ada code case)
- procedure Gen_Restrictions_C;
- -- Generate initialization of restrictions variable (C code case)
-
procedure Gen_Versions_Ada;
-- Output series of definitions for unit versions (Ada code case)
- procedure Gen_Versions_C;
- -- Output series of definitions for unit versions (C code case)
-
function Get_Ada_Main_Name return String;
-- This function is used in the Ada main output case to compute a usable
-- name for the generated main program. The normal main program name is
-- up all output unit numbers nicely as required by the value, and
-- by the total number of units.
- procedure Write_Info_Ada_C (Ada : String; C : String; Common : String);
- -- For C code case, write C & Common, for Ada case write Ada & Common
- -- to current binder output file using Write_Binder_Info.
-
procedure Write_Statement_Buffer;
-- Write out contents of statement buffer up to Last, and reset Last to 0
WBI ("");
end Gen_Adafinal_Ada;
- --------------------
- -- Gen_Adafinal_C --
- --------------------
-
- procedure Gen_Adafinal_C is
- begin
- WBI ("void " & Ada_Final_Name.all & " (void) {");
-
- WBI (" if (!is_elaborated)");
- WBI (" return;");
- WBI (" is_elaborated = 0;");
-
- if not Bind_Main_Program then
- if Lib_Final_Built then
- WBI (" finalize_library ();");
- end if;
-
- -- Main program case
-
- else
- WBI (" system__standard_library__adafinal ();");
- end if;
- WBI ("}");
- WBI ("");
- end Gen_Adafinal_C;
-
---------------------
-- Gen_Adainit_Ada --
---------------------
WBI ("");
end Gen_Adainit_Ada;
- -------------------
- -- Gen_Adainit_C --
- --------------------
-
- procedure Gen_Adainit_C is
- Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
- Main_CPU : Int renames ALIs.Table (ALIs.First).Main_CPU;
-
- begin
- WBI ("void " & Ada_Init_Name.all & " (void)");
- WBI ("{");
-
- WBI (" if (is_elaborated)");
- WBI (" return;");
- WBI (" is_elaborated = 1;");
-
- -- Standard library suppressed
-
- if Suppress_Standard_Library_On_Target then
-
- -- Case of High_Integrity_Mode mode. Set __gl_main_priority and
- -- __gl_main_cpu if needed for the Ravenscar profile.
-
- if Main_Priority /= No_Main_Priority then
- WBI (" extern int __gl_main_priority;");
- Set_String (" __gl_main_priority = ");
- Set_Int (Main_Priority);
- Set_Char (';');
- Write_Statement_Buffer;
- end if;
-
- if Main_CPU /= No_Main_CPU then
- WBI (" extern int __gl_main_cpu;");
- Set_String (" __gl_main_cpu = ");
- Set_Int (Main_CPU);
- Set_Char (';');
- Write_Statement_Buffer;
- end if;
-
- -- Normal case (standard library not suppressed)
-
- else
- -- Generate definition for interrupt states string
-
- Set_String (" static const char *local_interrupt_states = """);
-
- for J in 0 .. IS_Pragma_Settings.Last loop
- Set_Char (IS_Pragma_Settings.Table (J));
- end loop;
-
- Set_String (""";");
- Write_Statement_Buffer;
-
- -- Generate definition for priority specific dispatching string
-
- Set_String
- (" static const char *local_priority_specific_dispatching = """);
-
- for J in 0 .. PSD_Pragma_Settings.Last loop
- Set_Char (PSD_Pragma_Settings.Table (J));
- end loop;
-
- Set_String (""";");
- Write_Statement_Buffer;
-
- -- Generate declaration for secondary stack default if needed
-
- if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
- WBI (" extern int system__secondary_stack__" &
- "default_secondary_stack_size;");
- end if;
-
- WBI ("");
-
- -- Code for normal case (standard library not suppressed)
-
- -- We call the routine from inside adainit() because this works for
- -- both programs with and without binder generated "main" functions.
-
- WBI (" extern int __gl_main_priority;");
- Set_String (" __gl_main_priority = ");
- Set_Int (Main_Priority);
- Set_Char (';');
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_time_slice_val;");
- Set_String (" __gl_time_slice_val = ");
-
- if Task_Dispatching_Policy = 'F'
- and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
- then
- Set_Int (0);
- else
- Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
- end if;
-
- Set_Char (';');
- Write_Statement_Buffer;
-
- WBI (" extern char __gl_wc_encoding;");
- Set_String (" __gl_wc_encoding = '");
- Set_Char (Get_WC_Encoding);
-
- Set_String ("';");
- Write_Statement_Buffer;
-
- WBI (" extern char __gl_locking_policy;");
- Set_String (" __gl_locking_policy = '");
- Set_Char (Locking_Policy_Specified);
- Set_String ("';");
- Write_Statement_Buffer;
-
- WBI (" extern char __gl_queuing_policy;");
- Set_String (" __gl_queuing_policy = '");
- Set_Char (Queuing_Policy_Specified);
- Set_String ("';");
- Write_Statement_Buffer;
-
- WBI (" extern char __gl_task_dispatching_policy;");
- Set_String (" __gl_task_dispatching_policy = '");
- Set_Char (Task_Dispatching_Policy_Specified);
- Set_String ("';");
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_main_cpu;");
- Set_String (" __gl_main_cpu = ");
- Set_Int (Main_CPU);
- Set_Char (';');
- Write_Statement_Buffer;
-
- Gen_Restrictions_C;
-
- WBI (" extern const void *__gl_interrupt_states;");
- WBI (" __gl_interrupt_states = local_interrupt_states;");
-
- WBI (" extern int __gl_num_interrupt_states;");
- Set_String (" __gl_num_interrupt_states = ");
- Set_Int (IS_Pragma_Settings.Last + 1);
- Set_String (";");
- Write_Statement_Buffer;
-
- WBI (" extern const void *__gl_priority_specific_dispatching;");
- WBI (" __gl_priority_specific_dispatching =" &
- " local_priority_specific_dispatching;");
-
- WBI (" extern int __gl_num_specific_dispatching;");
- Set_String (" __gl_num_specific_dispatching = ");
- Set_Int (PSD_Pragma_Settings.Last + 1);
- Set_String (";");
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_unreserve_all_interrupts;");
- Set_String (" __gl_unreserve_all_interrupts = ");
- Set_Int (Boolean'Pos (Unreserve_All_Interrupts_Specified));
- Set_String (";");
- Write_Statement_Buffer;
-
- if Exception_Tracebacks then
- WBI (" extern int __gl_exception_tracebacks;");
- WBI (" __gl_exception_tracebacks = 1;");
- end if;
-
- WBI (" extern int __gl_zero_cost_exceptions;");
- Set_String (" __gl_zero_cost_exceptions = ");
- Set_Int (Boolean'Pos (Zero_Cost_Exceptions_Specified));
- Set_String (";");
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_detect_blocking;");
- Set_String (" __gl_detect_blocking = ");
-
- if Detect_Blocking then
- Set_Int (1);
- else
- Set_Int (0);
- end if;
-
- Set_String (";");
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_default_stack_size;");
- Set_String (" __gl_default_stack_size = ");
- Set_Int (Default_Stack_Size);
- Set_String (";");
- Write_Statement_Buffer;
-
- WBI (" extern int __gl_leap_seconds_support;");
- Set_String (" __gl_leap_seconds_support = ");
-
- if Leap_Seconds_Support then
- Set_Int (1);
- else
- Set_Int (0);
- end if;
-
- Set_String (";");
- Write_Statement_Buffer;
-
- -- Import entry point for elaboration time signal handler
- -- installation, and indication of if it's been called previously.
-
- WBI (" extern int __gnat_handler_installed;");
- WBI ("");
-
- -- Install elaboration time signal handler
-
- WBI (" if (__gnat_handler_installed == 0)");
- WBI (" __gnat_install_handler ();");
-
- -- Import entry point for environment feature enable/disable
- -- routine, and indication that it's been called previously.
-
- if OpenVMS_On_Target then
- WBI (" extern int __gnat_features_set;");
- WBI ("");
-
- WBI (" if (__gnat_features_set == 0)");
- WBI (" __gnat_set_features ();");
- end if;
- end if;
-
- -- Initialize stack limit for the environment task if the stack
- -- check method is stack limit and stack check is enabled.
-
- if Stack_Check_Limits_On_Target
- and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
- then
- WBI ("");
- WBI (" __gnat_initialize_stack_limit ();");
- end if;
-
- -- Generate call to set Initialize_Scalar values if needed
-
- if Initialize_Scalars_Used then
- WBI ("");
- Set_String (" system__scalar_values__initialize('");
- Set_Char (Initialize_Scalars_Mode1);
- Set_String ("', '");
- Set_Char (Initialize_Scalars_Mode2);
- Set_String ("');");
- Write_Statement_Buffer;
- end if;
-
- -- Generate assignment of default secondary stack size if set
-
- if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
- WBI ("");
- Set_String (" system__secondary_stack__");
- Set_String ("default_secondary_stack_size = ");
- Set_Int (Opt.Default_Sec_Stack_Size);
- Set_Char (';');
- Write_Statement_Buffer;
- end if;
-
- -- In the main program case, attach finalize_library to the soft link.
- -- Do it only when not using a restricted run time, in which case tasks
- -- are non-terminating, so we do not want library-level finalization.
-
- if Bind_Main_Program
- and then not Configurable_Run_Time_On_Target
- and then not Suppress_Standard_Library_On_Target
- then
- WBI ("");
- WBI (" extern void (*__gnat_finalize_library_objects)(void);");
-
- if Lib_Final_Built then
- Set_String (" __gnat_finalize_library_objects = ");
- Set_String ("&finalize_library;");
- else
- Set_String (" __gnat_finalize_library_objects = 0;");
- end if;
-
- Write_Statement_Buffer;
- end if;
-
- -- Generate elaboration calls
-
- WBI ("");
- Gen_Elab_Calls_C;
- WBI ("}");
- WBI ("");
- end Gen_Adainit_C;
-
----------------------------
-- Gen_Elab_Externals_Ada --
----------------------------
WBI ("");
end Gen_Elab_Externals_Ada;
- --------------------------
- -- Gen_Elab_Externals_C --
- --------------------------
-
- procedure Gen_Elab_Externals_C is
- begin
- for E in Elab_Order.First .. Elab_Order.Last loop
- declare
- Unum : constant Unit_Id := Elab_Order.Table (E);
- U : Unit_Record renames Units.Table (Unum);
-
- begin
- -- Check for Elab entity to be set for this unit
-
- if U.Set_Elab_Entity
-
- -- Don't generate reference for stand alone library
-
- and then not U.SAL_Interface
-
- -- Don't generate reference for predefined file in No_Run_Time
- -- mode, since we don't include the object files in this case
-
- and then not
- (No_Run_Time_Mode
- and then Is_Predefined_File_Name (U.Sfile))
- then
- Set_String ("extern short int ");
- Get_Name_String (U.Uname);
- Set_Unit_Name;
- Set_String ("_E;");
- Write_Statement_Buffer;
- end if;
- end;
- end loop;
-
- WBI ("");
- end Gen_Elab_Externals_C;
-
------------------------
-- Gen_Elab_Calls_Ada --
------------------------
end loop;
end Gen_Elab_Calls_Ada;
- ----------------------
- -- Gen_Elab_Calls_C --
- ----------------------
+ ------------------------
+ -- Gen_Elab_Order_Ada --
+ ------------------------
- procedure Gen_Elab_Calls_C is
+ procedure Gen_Elab_Order_Ada is
begin
- for E in Elab_Order.First .. Elab_Order.Last loop
- declare
- Unum : constant Unit_Id := Elab_Order.Table (E);
- U : Unit_Record renames Units.Table (Unum);
-
- Unum_Spec : Unit_Id;
- -- This is the unit number of the spec that corresponds to
- -- this entry. It is the same as Unum except when the body
- -- and spec are different and we are currently processing
- -- the body, in which case it is the spec (Unum + 1).
-
- begin
- if U.Utype = Is_Body then
- Unum_Spec := Unum + 1;
- else
- Unum_Spec := Unum;
- end if;
-
- -- Nothing to do if predefined unit in no run time mode
-
- if No_Run_Time_Mode and then Is_Predefined_File_Name (U.Sfile) then
- null;
-
- -- Likewise if this is an interface to a stand alone library
-
- elsif U.SAL_Interface then
- null;
-
- -- Case of no elaboration code
-
- elsif U.No_Elab 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 an elaboration entity defined. In that case, this is
- -- where we increment the elaboration entity.
-
- if U.Utype = Is_Body
- and then Units.Table (Unum_Spec).Set_Elab_Entity
- then
- Get_Name_String (U.Uname);
-
- Set_String (" ");
- Set_Unit_Name;
- Set_String ("_E++;");
- Write_Statement_Buffer;
- end if;
-
- -- Here if elaboration code is present. If binding a library
- -- or if there is a non-Ada main subprogram then we generate:
-
- -- if (uname_E == 0)
- -- uname__elab[s|b] ();
- -- uname_E++;
-
- -- Otherwise, elaboration routines are called unconditionally:
-
- -- uname__elab[s|b] ();
- -- uname_E++;
-
- -- The uname_E increment is skipped if this is a separate spec,
- -- since it will be done when we process the body.
-
- else
- Get_Name_String (U.Uname);
-
- if Force_Checking_Of_Elaboration_Flags
- or Interface_Library_Unit
- or not Bind_Main_Program
- then
- Set_String (" if (");
- Set_Unit_Name;
- Set_String ("_E == 0)");
- Write_Statement_Buffer;
- Set_String (" ");
- end if;
-
- Set_String (" ");
- Set_Unit_Name;
- Set_String ("___elab");
- Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
- Set_String (" ();");
- Write_Statement_Buffer;
-
- if U.Utype /= Is_Spec then
- Set_String (" ");
- Set_Unit_Name;
- Set_String ("_E++;");
- Write_Statement_Buffer;
- end if;
- end if;
- end;
- end loop;
- end Gen_Elab_Calls_C;
-
- ----------------------
- -- Gen_Elab_Defs_C --
- ----------------------
-
- procedure Gen_Elab_Defs_C is
- begin
- WBI ("/* BEGIN ELABORATION DEFINITIONS */");
-
- for E in Elab_Order.First .. Elab_Order.Last loop
-
- -- Generate declaration of elaboration procedure if elaboration
- -- needed. Note that passive units are always excluded.
-
- if not Units.Table (Elab_Order.Table (E)).No_Elab then
- Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
- Set_String ("extern void ");
- Set_Unit_Name;
- Set_String ("___elab");
- Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
- Set_String (" (void);");
- Write_Statement_Buffer;
- end if;
- end loop;
-
- WBI ("/* END ELABORATION DEFINITIONS */");
- WBI ("");
- end Gen_Elab_Defs_C;
-
- ------------------------
- -- Gen_Elab_Order_Ada --
- ------------------------
-
- procedure Gen_Elab_Order_Ada is
- begin
- WBI (" -- BEGIN ELABORATION ORDER");
+ WBI (" -- BEGIN ELABORATION ORDER");
for J in Elab_Order.First .. Elab_Order.Last loop
Set_String (" -- ");
WBI ("");
end Gen_Elab_Order_Ada;
- ----------------------
- -- Gen_Elab_Order_C --
- ----------------------
-
- procedure Gen_Elab_Order_C is
- begin
- WBI ("/* BEGIN ELABORATION ORDER");
-
- for J in Elab_Order.First .. Elab_Order.Last loop
- Get_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
- Set_Name_Buffer;
- Write_Statement_Buffer;
- end loop;
-
- WBI (" END ELABORATION ORDER */");
- WBI ("");
- end Gen_Elab_Order_C;
-
------------------------------
-- Gen_Finalize_Library_Ada --
------------------------------
end if;
end Gen_Finalize_Library_Ada;
- ----------------------------
- -- Gen_Finalize_Library_C --
- ----------------------------
-
- procedure Gen_Finalize_Library_C is
- U : Unit_Record;
- 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' or else U.Is_Generic then
- null;
-
- -- .. that are not interfaces to a stand alone library
-
- elsif U.SAL_Interface then
- null;
-
- -- 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;
-
- 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:
-
- -- uname_E--;
- -- if (uname_E == 0)
- -- uname__finalize_[spec|body] ();
-
- -- Otherwise, finalization routines are called unconditionally:
-
- -- uname_E--;
- -- uname__finalize_[spec|body] ();
-
- -- 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 (");
- Set_Unit_Name;
- Set_String ("_E == 0)");
- Write_Statement_Buffer;
- Set_String (" ");
- end if;
-
- Set_String (" ");
- Get_Name_String (Uspec.Uname);
- Set_Unit_Name;
- Set_String ("__finalize_");
-
- -- Package spec processing
-
- if U.Utype = Is_Spec
- or else U.Utype = Is_Spec_Only
- then
- Set_String ("spec");
-
- -- Package body processing
-
- else
- Set_String ("body");
- end if;
-
- Set_String (" ();");
-
- Write_Statement_Buffer;
- end if;
- end loop;
-
- if Lib_Final_Built then
- WBI ("}");
- WBI ("");
- end if;
- end Gen_Finalize_Library_C;
-
- ---------------------------------
- -- Gen_Finalize_Library_Defs_C --
- ---------------------------------
-
- procedure Gen_Finalize_Library_Defs_C is
- U : Unit_Record;
- Uspec : Unit_Record;
- Unum : Unit_Id;
-
- begin
- WBI ("/* BEGIN FINALIZE DEFINITIONS */");
-
- for E in reverse Elab_Order.First .. Elab_Order.Last loop
- Unum := Elab_Order.Table (E);
- U := Units.Table (Unum);
-
- -- 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.No_Elab
- then
- -- 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;
-
- Set_String ("extern void ");
- Get_Name_String (Uspec.Uname);
- Set_Unit_Name;
- Set_String ("__finalize_");
-
- if U.Utype = Is_Spec
- or else U.Utype = Is_Spec_Only
- then
- Set_String ("spec");
- else
- Set_String ("body");
- end if;
-
- Set_String (" (void);");
- Write_Statement_Buffer;
- end if;
- end loop;
-
- WBI ("/* END FINALIZE DEFINITIONS */");
- WBI ("");
- end Gen_Finalize_Library_Defs_C;
-
--------------------------
-- Gen_CodePeer_Wrapper --
--------------------------
if Dynamic_Stack_Measurement then
WBI (" Output_Results;");
- end if;
-
- -- Finalize is only called if we have a run time
-
- if not Cumulative_Restrictions.Set (No_Finalization)
- and then not CodePeer_Mode
- then
- WBI (" Finalize;");
- end if;
-
- -- Return result
-
- if Exit_Status_Supported_On_Target then
- if No_Main_Subprogram
- or else ALIs.Table (ALIs.First).Main_Program = Proc
- then
- WBI (" return (gnat_exit_status);");
- else
- WBI (" return (Result);");
- end if;
- end if;
-
- WBI (" end;");
- WBI ("");
- end Gen_Main_Ada;
-
- ----------------
- -- Gen_Main_C --
- ----------------
-
- procedure Gen_Main_C is
- begin
- if Exit_Status_Supported_On_Target then
- WBI ("#include <stdlib.h>");
- WBI ("");
- Set_String ("int ");
- else
- Set_String ("void ");
- end if;
-
- Set_String (Get_Main_Name);
-
- -- Generate command line args in prototype if present on target
-
- if Command_Line_Args_On_Target then
- Write_Statement_Buffer (" (int argc, char **argv, char **envp)");
-
- -- Case of no command line arguments on target
-
- else
- Write_Statement_Buffer (" (void)");
- end if;
-
- WBI ("{");
-
- -- Generate a reference to __gnat_ada_main_program_name. This symbol
- -- is not referenced elsewhere in the generated program, but is
- -- needed by the debugger (that's why it is generated in the first
- -- place). The reference stops Ada_Main_Program_Name from being
- -- optimized away by smart linkers, such as the AiX linker.
-
- -- Because this variable is unused, we declare this variable as
- -- volatile in order to tell the compiler to preserve it at any
- -- level of optimization.
-
- if Bind_Main_Program then
- WBI (" char * volatile ensure_reference " &
- "__attribute__ ((__unused__)) = " &
- "__gnat_ada_main_program_name;");
- WBI ("");
-
- if not Suppress_Standard_Library_On_Target
- and then not No_Main_Subprogram
- then
- WBI (" int SEH [2];");
- WBI ("");
- end if;
- end if;
-
- -- If main program is a function, generate result variable
-
- if ALIs.Table (ALIs.First).Main_Program = Func then
- WBI (" int result;");
- end if;
-
- -- Set command line argument values from parameters if command line
- -- arguments are present on target
-
- if Command_Line_Args_On_Target then
- WBI (" gnat_argc = argc;");
- WBI (" gnat_argv = argv;");
- WBI (" gnat_envp = envp;");
- WBI ("");
-
- -- If configurable run-time, then nothing to do, since in this case
- -- the gnat_argc/argv/envp variables are entirely suppressed.
-
- elsif Configurable_Run_Time_On_Target then
- null;
-
- -- if no command line arguments on target, set dummy values
-
- else
- WBI (" gnat_argc = 0;");
- WBI (" gnat_argv = 0;");
- WBI (" gnat_envp = 0;");
- end if;
-
- if Opt.Default_Exit_Status /= 0
- and then Bind_Main_Program
- and then not Configurable_Run_Time_Mode
- then
- Set_String (" __gnat_set_exit_status (");
- Set_Int (Opt.Default_Exit_Status);
- Set_String (");");
- Write_Statement_Buffer;
- end if;
-
- -- Initializes dynamic stack measurement if needed
-
- if Dynamic_Stack_Measurement then
- Set_String (" __gnat_stack_usage_initialize (");
- Set_Int (Dynamic_Stack_Measurement_Array_Size);
- Set_String (");");
- Write_Statement_Buffer;
- end if;
-
- -- The __gnat_initialize routine is used only if we have a run-time
-
- if not Suppress_Standard_Library_On_Target then
- if not No_Main_Subprogram and then Bind_Main_Program then
- WBI (" __gnat_initialize ((void *)SEH);");
- else
- WBI (" __gnat_initialize ((void *)0);");
- end if;
- end if;
-
- WBI (" " & Ada_Init_Name.all & " ();");
-
- if not No_Main_Subprogram then
-
- -- Output main program name
-
- Get_Name_String (Units.Table (First_Unit_Entry).Uname);
-
- -- Main program is procedure case
-
- if ALIs.Table (ALIs.First).Main_Program = Proc then
- Set_String (" ");
- Set_Main_Program_Name;
- Set_String (" ();");
- Write_Statement_Buffer;
-
- -- Main program is function case
-
- else -- ALIs.Table (ALIs_First).Main_Program = Func
- Set_String (" result = ");
- Set_Main_Program_Name;
- Set_String (" ();");
- Write_Statement_Buffer;
- end if;
-
- end if;
-
- -- Call adafinal if finalization active
-
- if not Cumulative_Restrictions.Set (No_Finalization) then
- WBI (" " & Ada_Final_Name.all & " ();");
- end if;
-
- -- Outputs the dynamic stack measurement if needed
-
- if Dynamic_Stack_Measurement then
- WBI (" __gnat_stack_usage_output_results ();");
- end if;
-
- -- The finalize routine is used only if we have a run-time
-
- if not Suppress_Standard_Library_On_Target then
- WBI (" __gnat_finalize ();");
- end if;
-
- -- Case of main program is a function, so the value it returns
- -- is the exit status in this case.
-
- if ALIs.Table (ALIs.First).Main_Program = Func then
- if Exit_Status_Supported_On_Target then
-
- -- VMS must use Posix exit routine in order to get the effect
- -- of a Unix compatible setting of the program exit status.
- -- For all other systems, we use the standard exit routine.
-
- if OpenVMS_On_Target then
- WBI (" decc$__posix_exit (result);");
- else
- WBI (" exit (result);");
- end if;
- end if;
+ end if;
- -- Case of main program is a procedure, in which case the exit
- -- status is whatever was set by a Set_Exit call most recently
+ -- Finalize is only called if we have a run time
- else
- if Exit_Status_Supported_On_Target then
+ if not Cumulative_Restrictions.Set (No_Finalization)
+ and then not CodePeer_Mode
+ then
+ WBI (" Finalize;");
+ end if;
- -- VMS must use Posix exit routine in order to get the effect
- -- of a Unix compatible setting of the program exit status.
- -- For all other systems, we use the standard exit routine.
+ -- Return result
- if OpenVMS_On_Target then
- WBI (" decc$__posix_exit (gnat_exit_status);");
- else
- WBI (" exit (gnat_exit_status);");
- end if;
+ if Exit_Status_Supported_On_Target then
+ if No_Main_Subprogram
+ or else ALIs.Table (ALIs.First).Main_Program = Proc
+ then
+ WBI (" return (gnat_exit_status);");
+ else
+ WBI (" return (Result);");
end if;
end if;
- WBI ("}");
+ WBI (" end;");
WBI ("");
- end Gen_Main_C;
+ end Gen_Main_Ada;
------------------------------
-- Gen_Object_Files_Options --
Write_Str (Name_Buffer (Start .. Stop - 1));
Write_Eol;
end if;
- Write_Info_Ada_C
- (" -- ", "", Name_Buffer (Start .. Stop - 1));
+ WBI (" -- " & Name_Buffer (Start .. Stop - 1));
end if;
Start := Stop + 1;
-- Start of processing for Gen_Object_Files_Options
begin
- Write_Info_Ada_C ("-- ", "/* ", " BEGIN Object file/option list");
+ WBI ("-- BEGIN Object file/option list");
if Object_List_Filename /= null then
Set_List_File (Object_List_Filename.all);
or else
System.OS_Lib.Is_Regular_File (Name_Buffer (1 .. Name_Len))
then
- Write_Info_Ada_C (" -- ", "", Name_Buffer (1 .. Name_Len));
+ WBI (" -- " & Name_Buffer (1 .. Name_Len));
if Output_Object_List then
Write_Str (Name_Buffer (1 .. Name_Len));
-- Write directly to avoid -K output (why???)
- Write_Info_Ada_C (" -- ", "", Name_Buffer (1 .. Name_Len));
+ WBI (" -- " & Name_Buffer (1 .. Name_Len));
if With_DECGNAT then
Name_Len := 0;
Write_Eol;
end if;
- if Ada_Bind_File then
- WBI ("-- END Object file/option list ");
- else
- WBI (" END Object file/option list */");
- end if;
+ WBI ("-- END Object file/option list ");
end Gen_Object_Files_Options;
---------------------
Set_PSD_Pragma_Table;
- -- Override Ada_Bind_File and Bind_Main_Program for VMs since JGNAT only
- -- supports Ada code, and the main program is already generated by the
- -- compiler.
-
- if VM_Target /= No_VM then
- Ada_Bind_File := True;
+ -- For JGNAT the main program is already generated by the compiler
- if VM_Target = JVM_Target then
- Bind_Main_Program := False;
- end if;
+ if VM_Target = JVM_Target then
+ Bind_Main_Program := False;
end if;
-- Override time slice value if -T switch is set
Check_System_Restrictions_Used;
- if Ada_Bind_File then
- Gen_Output_File_Ada (Filename);
- else
- Gen_Output_File_C (Filename);
- end if;
+ Gen_Output_File_Ada (Filename);
end Gen_Output_File;
-------------------------
Close_Binder_Output;
end Gen_Output_File_Ada;
- -----------------------
- -- Gen_Output_File_C --
- -----------------------
-
- procedure Gen_Output_File_C (Filename : String) is
-
- Needs_Library_Finalization : constant Boolean :=
- not Configurable_Run_Time_On_Target
- and then Has_Finalizer;
- -- ??? seems like we repeat this cantation often, should it be global?
-
- Bfile : Name_Id;
- pragma Warnings (Off, Bfile);
- -- Name of generated bind file (not referenced)
-
- begin
- Create_Binder_Output (Filename, 'c', Bfile);
-
- Resolve_Binder_Options;
-
- -- If -a has been specified use __attribute__((constructor)) for the
- -- init procedure and __attribute__((destructor)) for the final one.
-
- if Use_Pragma_Linker_Constructor then
- WBI ("extern void " & Ada_Init_Name.all &
- " (void) __attribute__((constructor));");
- else
- WBI ("extern void " & Ada_Init_Name.all & " (void);");
- end if;
-
- if not Cumulative_Restrictions.Set (No_Finalization) then
- if Use_Pragma_Linker_Constructor then
- WBI ("extern void " & Ada_Final_Name.all &
- " (void) __attribute__((destructor));");
- else
- WBI ("extern void " & Ada_Final_Name.all & " (void);");
- end if;
- end if;
-
- WBI ("extern void system__standard_library__adafinal (void);");
-
- if not No_Main_Subprogram then
- Set_String ("extern ");
-
- if Exit_Status_Supported_On_Target then
- Set_String ("int");
- else
- Set_String ("void");
- end if;
-
- Set_String (" main ");
-
- if Command_Line_Args_On_Target then
- Write_Statement_Buffer ("(int, char **, char **);");
- else
- Write_Statement_Buffer ("(void);");
- end if;
-
- if OpenVMS_On_Target then
- WBI ("extern void decc$__posix_exit (int);");
- else
- WBI ("extern void exit (int);");
- end if;
-
- Set_String ("extern ");
-
- if ALIs.Table (ALIs.First).Main_Program = Proc then
- Set_String ("void ");
- else
- Set_String ("int ");
- end if;
-
- Get_Name_String (Units.Table (First_Unit_Entry).Uname);
- Set_Main_Program_Name;
- Set_String (" (void);");
- Write_Statement_Buffer;
- end if;
-
- if not Suppress_Standard_Library_On_Target then
- WBI ("extern void __gnat_initialize (void *);");
- WBI ("extern void __gnat_finalize (void);");
- WBI ("extern void __gnat_install_handler (void);");
- end if;
-
- if Dynamic_Stack_Measurement then
- WBI ("");
- WBI ("extern void __gnat_stack_usage_output_results (void);");
- WBI ("extern void __gnat_stack_usage_initialize (int size);");
- end if;
-
- -- Initialize stack limit for the environment task if the stack check
- -- method is stack limit and stack check is enabled.
-
- if Stack_Check_Limits_On_Target
- and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
- then
- WBI ("");
- WBI ("extern void __gnat_initialize_stack_limit (void);");
- end if;
-
- WBI ("");
-
- -- Generate externals for elaboration entities
- Gen_Elab_Externals_C;
-
- Gen_Elab_Defs_C;
-
- if Needs_Library_Finalization then
- Gen_Finalize_Library_Defs_C;
- end if;
-
- -- Write argv/argc exit status stuff if main program case
-
- if Bind_Main_Program then
-
- -- First deal with argc/argv/envp. In the normal case they are in the
- -- run-time library.
-
- if not Configurable_Run_Time_On_Target then
- WBI ("extern int gnat_argc;");
- WBI ("extern char **gnat_argv;");
- WBI ("extern char **gnat_envp;");
-
- -- If configurable run time and no command line args, then the
- -- generation of these variables is entirely suppressed.
-
- elsif not Command_Line_Args_On_Target then
- null;
-
- -- Otherwise, in the configurable run-time case they are right in the
- -- binder file.
-
- else
- WBI ("int gnat_argc;");
- WBI ("char **gnat_argv;");
- WBI ("char **gnat_envp;");
- end if;
-
- -- Similarly deal with exit status
-
- if not Configurable_Run_Time_On_Target then
- WBI ("extern int gnat_exit_status;");
-
- -- If configurable run time and no exit status on target, then the
- -- generation of this variables is entirely suppressed.
-
- elsif not Exit_Status_Supported_On_Target then
- null;
-
- -- Otherwise, in the configurable run-time case this variable is
- -- right in the binder file, and initialized to zero there.
-
- else
- WBI ("int gnat_exit_status = 0;");
- end if;
-
- WBI ("");
- end if;
-
- -- Generate the __gnat_version and __gnat_ada_main_program_name info
- -- only for the main program. Otherwise, it can lead under some
- -- circumstances to a symbol duplication during the link (for instance
- -- when a C program uses 2 Ada libraries)
-
- if Bind_Main_Program then
- WBI ("char __gnat_version[] = """ & Ver_Prefix &
- Gnat_Version_String & """;");
-
- Set_String ("char __gnat_ada_main_program_name[] = """);
- Get_Name_String (Units.Table (First_Unit_Entry).Uname);
- Set_Main_Program_Name;
- Set_String (""";");
- Write_Statement_Buffer;
- WBI ("");
- end if;
-
- -- The B.1 (39) implementation advice says that the adainit/adafinal
- -- routines should be idempotent. Generate a flag to ensure that.
-
- WBI ("static char is_elaborated = 0;");
- WBI ("");
-
- -- Generate the adafinal routine unless there is no finalization to do
-
- if not Cumulative_Restrictions.Set (No_Finalization) then
- if Needs_Library_Finalization then
- Gen_Finalize_Library_C;
- end if;
-
- Gen_Adafinal_C;
- end if;
-
- Gen_Adainit_C;
-
- -- Main is only present for Ada main case
-
- if Bind_Main_Program then
- Gen_Main_C;
- end if;
-
- -- Generate versions, elaboration order, list of object files
-
- Gen_Versions_C;
- Gen_Elab_Order_C;
- Gen_Object_Files_Options;
-
- -- C binder output is complete
-
- Close_Binder_Output;
- end Gen_Output_File_C;
-
--------------------------
-- Gen_Restrictions_Ada --
--------------------------
Write_Statement_Buffer;
end Gen_Restrictions_Ada;
- ------------------------
- -- Gen_Restrictions_C --
- ------------------------
-
- procedure Gen_Restrictions_C is
- begin
- if Suppress_Standard_Library_On_Target
- or not System_Restrictions_Used
- then
- return;
- end if;
-
- WBI (" typedef struct {");
- Set_String (" char set [");
- Set_Int (Cumulative_Restrictions.Set'Length);
- Set_String ("];");
- Write_Statement_Buffer;
-
- Set_String (" int value [");
- Set_Int (Cumulative_Restrictions.Value'Length);
- Set_String ("];");
- Write_Statement_Buffer;
-
- Set_String (" char violated [");
- Set_Int (Cumulative_Restrictions.Violated'Length);
- Set_String ("];");
- Write_Statement_Buffer;
-
- Set_String (" int count [");
- Set_Int (Cumulative_Restrictions.Count'Length);
- Set_String ("];");
- Write_Statement_Buffer;
-
- Set_String (" char unknown [");
- Set_Int (Cumulative_Restrictions.Unknown'Length);
- Set_String ("];");
- Write_Statement_Buffer;
- WBI (" } restrictions;");
- WBI (" extern restrictions " &
- "system__restrictions__run_time_restrictions;");
- WBI (" restrictions r = {");
- Set_String (" {");
-
- for J in Cumulative_Restrictions.Set'Range loop
- Set_Int (Boolean'Pos (Cumulative_Restrictions.Set (J)));
- Set_String (", ");
- end loop;
-
- Set_String_Replace ("},");
- Write_Statement_Buffer;
- Set_String (" {");
-
- for J in Cumulative_Restrictions.Value'Range loop
- Set_Int (Int (Cumulative_Restrictions.Value (J)));
- Set_String (", ");
- end loop;
-
- Set_String_Replace ("},");
- Write_Statement_Buffer;
- Set_String (" {");
-
- for J in Cumulative_Restrictions.Violated'Range loop
- Set_Int (Boolean'Pos (Cumulative_Restrictions.Violated (J)));
- Set_String (", ");
- end loop;
-
- Set_String_Replace ("},");
- Write_Statement_Buffer;
- Set_String (" {");
-
- for J in Cumulative_Restrictions.Count'Range loop
- Set_Int (Int (Cumulative_Restrictions.Count (J)));
- Set_String (", ");
- end loop;
-
- Set_String_Replace ("},");
- Write_Statement_Buffer;
- Set_String (" {");
-
- for J in Cumulative_Restrictions.Unknown'Range loop
- Set_Int (Boolean'Pos (Cumulative_Restrictions.Unknown (J)));
- Set_String (", ");
- end loop;
-
- Set_String_Replace ("}}");
- Set_String (";");
- Write_Statement_Buffer;
- WBI (" system__restrictions__run_time_restrictions = r;");
- end Gen_Restrictions_C;
-
----------------------
-- Gen_Versions_Ada --
----------------------
end loop;
end Gen_Versions_Ada;
- --------------------
- -- Gen_Versions_C --
- --------------------
-
- -- This routine generates a line of the form:
-
- -- unsigned unam = 0xhhhhhhhh;
-
- -- for each unit, where unam is the unit name suffixed by either B or S for
- -- body or spec, with dots replaced by double underscores.
-
- procedure Gen_Versions_C is
- begin
- for U in Units.First .. Units.Last loop
- if not Units.Table (U).SAL_Interface
- and then
- (not Bind_For_Library or else Units.Table (U).Directly_Scanned)
- then
- Set_String ("unsigned ");
-
- Get_Name_String (Units.Table (U).Uname);
-
- for K in 1 .. Name_Len loop
- if Name_Buffer (K) = '.' then
- Set_String ("__");
-
- elsif Name_Buffer (K) = '%' then
- exit;
-
- else
- Set_Char (Name_Buffer (K));
- end if;
- end loop;
-
- if Name_Buffer (Name_Len) = 's' then
- Set_Char ('S');
- else
- Set_Char ('B');
- end if;
-
- Set_String (" = 0x");
- Set_String (Units.Table (U).Version);
- Set_Char (';');
- Write_Statement_Buffer;
- end if;
- end loop;
- end Gen_Versions_C;
-
------------------------
-- Get_Main_Unit_Name --
------------------------
Set_Int (Unum);
end Set_Unit_Number;
- ----------------------
- -- Write_Info_Ada_C --
- ----------------------
-
- procedure Write_Info_Ada_C (Ada : String; C : String; Common : String) is
- begin
- if Ada_Bind_File then
- declare
- S : String (1 .. Ada'Length + Common'Length);
- begin
- S (1 .. Ada'Length) := Ada;
- S (Ada'Length + 1 .. S'Length) := Common;
- WBI (S);
- end;
-
- else
- declare
- S : String (1 .. C'Length + Common'Length);
- begin
- S (1 .. C'Length) := C;
- S (C'Length + 1 .. S'Length) := Common;
- WBI (S);
- end;
- end if;
- end Write_Info_Ada_C;
-
----------------------------
-- Write_Statement_Buffer --
----------------------------