OSDN Git Service

b88ed0019f7a9b2812d46b2325dc274f9e11e08d
[pf3gnuchains/gcc-fork.git] / gcc / ada / bindgen.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              B I N D G E N                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with ALI;      use ALI;
27 with Binde;    use Binde;
28 with Casing;   use Casing;
29 with Fname;    use Fname;
30 with Gnatvsn;  use Gnatvsn;
31 with Hostparm;
32 with Namet;    use Namet;
33 with Opt;      use Opt;
34 with Osint;    use Osint;
35 with Osint.B;  use Osint.B;
36 with Output;   use Output;
37 with Rident;   use Rident;
38 with Table;    use Table;
39 with Targparm; use Targparm;
40 with Types;    use Types;
41
42 with System.OS_Lib;  use System.OS_Lib;
43 with System.WCh_Con; use System.WCh_Con;
44
45 with GNAT.Heap_Sort_A; use GNAT.Heap_Sort_A;
46
47 package body Bindgen is
48
49    Statement_Buffer : String (1 .. 1000);
50    --  Buffer used for constructing output statements
51
52    Last : Natural := 0;
53    --  Last location in Statement_Buffer currently set
54
55    With_DECGNAT : Boolean := False;
56    --  Flag which indicates whether the program uses the DECGNAT library
57    --  (presence of the unit DEC).
58
59    With_GNARL : Boolean := False;
60    --  Flag which indicates whether the program uses the GNARL library
61    --  (presence of the unit System.OS_Interface)
62
63    Num_Elab_Calls : Nat := 0;
64    --  Number of generated calls to elaboration routines
65
66    System_Restrictions_Used : Boolean;
67    --  Flag indicating whether the unit System.Restrictions is in the closure
68    --  of the partition. This is set by Check_System_Restrictions_Used, and
69    --  is used to determine whether or not to initialize the restrictions
70    --  information in the body of the binder generated file (we do not want
71    --  to do this unconditionally, since it drags in the System.Restrictions
72    --  unit unconditionally, which is unpleasand, especially for ZFP etc.)
73
74    Lib_Final_Built : Boolean := False;
75
76    ----------------------------------
77    -- Interface_State Pragma Table --
78    ----------------------------------
79
80    --  This table assembles the interface state pragma information from
81    --  all the units in the partition. Note that Bcheck has already checked
82    --  that the information is consistent across units. The entries
83    --  in this table are n/u/r/s for not set/user/runtime/system.
84
85    package IS_Pragma_Settings is new Table.Table (
86      Table_Component_Type => Character,
87      Table_Index_Type     => Int,
88      Table_Low_Bound      => 0,
89      Table_Initial        => 100,
90      Table_Increment      => 200,
91      Table_Name           => "IS_Pragma_Settings");
92
93    --  This table assembles the Priority_Specific_Dispatching pragma
94    --  information from all the units in the partition. Note that Bcheck has
95    --  already checked that the information is consistent across units.
96    --  The entries in this table are the upper case first character of the
97    --  policy name, e.g. 'F' for FIFO_Within_Priorities.
98
99    package PSD_Pragma_Settings is new Table.Table (
100      Table_Component_Type => Character,
101      Table_Index_Type     => Int,
102      Table_Low_Bound      => 0,
103      Table_Initial        => 100,
104      Table_Increment      => 200,
105      Table_Name           => "PSD_Pragma_Settings");
106
107    ----------------------
108    -- Run-Time Globals --
109    ----------------------
110
111    --  This section documents the global variables that set from the
112    --  generated binder file.
113
114    --     Main_Priority                 : Integer;
115    --     Time_Slice_Value              : Integer;
116    --     Heap_Size                     : Natural;
117    --     WC_Encoding                   : Character;
118    --     Locking_Policy                : Character;
119    --     Queuing_Policy                : Character;
120    --     Task_Dispatching_Policy       : Character;
121    --     Priority_Specific_Dispatching : System.Address;
122    --     Num_Specific_Dispatching      : Integer;
123    --     Restrictions                  : System.Address;
124    --     Interrupt_States              : System.Address;
125    --     Num_Interrupt_States          : Integer;
126    --     Unreserve_All_Interrupts      : Integer;
127    --     Exception_Tracebacks          : Integer;
128    --     Zero_Cost_Exceptions          : Integer;
129    --     Detect_Blocking               : Integer;
130    --     Default_Stack_Size            : Integer;
131    --     Leap_Seconds_Support          : Integer;
132    --     Main_CPU                      : Integer;
133
134    --  Main_Priority is the priority value set by pragma Priority in the main
135    --  program. If no such pragma is present, the value is -1.
136
137    --  Time_Slice_Value is the time slice value set by pragma Time_Slice in the
138    --  main program, or by the use of a -Tnnn parameter for the binder (if both
139    --  are present, the binder value overrides). The value is in milliseconds.
140    --  A value of zero indicates that time slicing should be suppressed. If no
141    --  pragma is present, and no -T switch was used, the value is -1.
142
143    --  Heap_Size is the heap to use for memory allocations set by use of a
144    --  -Hnn parameter for the binder or by the GNAT$NO_MALLOC_64 logical.
145    --  Valid values are 32 and 64. This switch is only effective on VMS.
146
147    --  WC_Encoding shows the wide character encoding method used for the main
148    --  program. This is one of the encoding letters defined in
149    --  System.WCh_Con.WC_Encoding_Letters.
150
151    --  Locking_Policy is a space if no locking policy was specified for the
152    --  partition. If a locking policy was specified, the value is the upper
153    --  case first character of the locking policy name, for example, 'C' for
154    --  Ceiling_Locking.
155
156    --  Queuing_Policy is a space if no queuing policy was specified for the
157    --  partition. If a queuing policy was specified, the value is the upper
158    --  case first character of the queuing policy name for example, 'F' for
159    --  FIFO_Queuing.
160
161    --  Task_Dispatching_Policy is a space if no task dispatching policy was
162    --  specified for the partition. If a task dispatching policy was specified,
163    --  the value is the upper case first character of the policy name, e.g. 'F'
164    --  for FIFO_Within_Priorities.
165
166    --  Priority_Specific_Dispatching is the address of a string used to store
167    --  the task dispatching policy specified for the different priorities in
168    --  the partition. The length of this string is determined by the last
169    --  priority for which such a pragma applies (the string will be a null
170    --  string if no specific dispatching policies were used). If pragma were
171    --  present, the entries apply to the priorities in sequence from the first
172    --  priority. The value stored is the upper case first character of the
173    --  policy name, or 'F' (for FIFO_Within_Priorities) as the default value
174    --  for those priority ranges not specified.
175
176    --  Num_Specific_Dispatching is the length of the
177    --  Priority_Specific_Dispatching string. It will be set to zero if no
178    --  Priority_Specific_Dispatching pragmas are present.
179
180    --  Restrictions is the address of a null-terminated string specifying the
181    --  restrictions information for the partition. The format is identical to
182    --  that of the parameter string found on R lines in ali files (see Lib.Writ
183    --  spec in lib-writ.ads for full details). The difference is that in this
184    --  context the values are the cumulative ones for the entire partition.
185
186    --  Interrupt_States is the address of a string used to specify the
187    --  cumulative results of Interrupt_State pragmas used in the partition.
188    --  The length of this string is determined by the last interrupt for which
189    --  such a pragma is given (the string will be a null string if no pragmas
190    --  were used). If pragma were present the entries apply to the interrupts
191    --  in sequence from the first interrupt, and are set to one of four
192    --  possible settings: 'n' for not specified, 'u' for user, 'r' for run
193    --  time, 's' for system, see description of Interrupt_State pragma for
194    --  further details.
195
196    --  Num_Interrupt_States is the length of the Interrupt_States string. It
197    --  will be set to zero if no Interrupt_State pragmas are present.
198
199    --  Unreserve_All_Interrupts is set to one if at least one unit in the
200    --  partition had a pragma Unreserve_All_Interrupts, and zero otherwise.
201
202    --  Exception_Tracebacks is set to one if the -E parameter was present
203    --  in the bind and to zero otherwise. Note that on some targets exception
204    --  tracebacks are provided by default, so a value of zero for this
205    --  parameter does not necessarily mean no trace backs are available.
206
207    --  Zero_Cost_Exceptions is set to one if zero cost exceptions are used for
208    --  this partition, and to zero if longjmp/setjmp exceptions are used.
209
210    --  Detect_Blocking indicates whether pragma Detect_Blocking is active or
211    --  not. A value of zero indicates that the pragma is not present, while a
212    --  value of 1 signals its presence in the partition.
213
214    --  Default_Stack_Size is the default stack size used when creating an Ada
215    --  task with no explicit Storage_Size clause.
216
217    --  Leap_Seconds_Support denotes whether leap seconds have been enabled or
218    --  disabled. A value of zero indicates that leap seconds are turned "off",
219    --  while a value of one signifies "on" status.
220
221    --  Main_CPU is the processor set by pragma CPU in the main program. If no
222    --  such pragma is present, the value is -1.
223
224    -----------------------
225    -- Local Subprograms --
226    -----------------------
227
228    procedure WBI (Info : String) renames Osint.B.Write_Binder_Info;
229    --  Convenient shorthand used throughout
230
231    procedure Check_System_Restrictions_Used;
232    --  Sets flag System_Restrictions_Used (Set to True if and only if the unit
233    --  System.Restrictions is present in the partition, otherwise False).
234
235    procedure Gen_Adainit_Ada;
236    --  Generates the Adainit procedure (Ada code case)
237
238    procedure Gen_Adainit_C;
239    --  Generates the Adainit procedure (C code case)
240
241    procedure Gen_Adafinal_Ada;
242    --  Generate the Adafinal procedure (Ada code case)
243
244    procedure Gen_Adafinal_C;
245    --  Generate the Adafinal procedure (C code case)
246
247    procedure Gen_Elab_Calls_Ada;
248    --  Generate sequence of elaboration calls (Ada code case)
249
250    procedure Gen_Elab_Calls_C;
251    --  Generate sequence of elaboration calls (C code case)
252
253    procedure Gen_Elab_Order_Ada;
254    --  Generate comments showing elaboration order chosen (Ada code case)
255
256    procedure Gen_Elab_Order_C;
257    --  Generate comments showing elaboration order chosen (C code case)
258
259    procedure Gen_Elab_Defs_C;
260    --  Generate sequence of definitions for elaboration routines (C code case)
261
262    procedure Gen_Finalize_Library_Ada;
263    --  Generate a sequence of finalization calls to elaborated packages (Ada)
264
265    procedure Gen_Finalize_Library_C;
266    --  Generate a sequence of finalization calls to elaborated packages (C)
267
268    procedure Gen_Finalize_Library_Defs_C;
269    --  Generate a sequence of defininitions for package finalizers (C case)
270
271    procedure Gen_Main_Ada;
272    --  Generate procedure main (Ada code case)
273
274    procedure Gen_Main_C;
275    --  Generate main() procedure (C code case)
276
277    procedure Gen_Object_Files_Options;
278    --  Output comments containing a list of the full names of the object
279    --  files to be linked and the list of linker options supplied by
280    --  Linker_Options pragmas in the source. (C and Ada code case)
281
282    procedure Gen_Output_File_Ada (Filename : String);
283    --  Generate output file (Ada code case)
284
285    procedure Gen_Output_File_C (Filename : String);
286    --  Generate output file (C code case)
287
288    procedure Gen_Restrictions_Ada;
289    --  Generate initialization of restrictions variable (Ada code case)
290
291    procedure Gen_Restrictions_C;
292    --  Generate initialization of restrictions variable (C code case)
293
294    procedure Gen_Versions_Ada;
295    --  Output series of definitions for unit versions (Ada code case)
296
297    procedure Gen_Versions_C;
298    --  Output series of definitions for unit versions (C code case)
299
300    function Get_Ada_Main_Name return String;
301    --  This function is used in the Ada main output case to compute a usable
302    --  name for the generated main program. The normal main program name is
303    --  Ada_Main, but this won't work if the user has a unit with this name.
304    --  This function tries Ada_Main first, and if there is such a clash, then
305    --  it tries Ada_Name_01, Ada_Name_02 ... Ada_Name_99 in sequence.
306
307    function Get_Main_Unit_Name (S : String) return String;
308    --  Return the main unit name corresponding to S by replacing '.' with '_'
309
310    function Get_Main_Name return String;
311    --  This function is used in the Ada main output case to compute the
312    --  correct external main program. It is "main" by default, unless the
313    --  flag Use_Ada_Main_Program_Name_On_Target is set, in which case it
314    --  is the name of the Ada main name without the "_ada". This default
315    --  can be overridden explicitly using the -Mname binder switch.
316
317    function Get_WC_Encoding return Character;
318    --  Return wide character encoding method to set as WC_Encoding in output.
319    --  If -W has been used, returns the specified encoding, otherwise returns
320    --  the encoding method used for the main program source. If there is no
321    --  main program source (-z switch used), returns brackets ('b').
322
323    function Has_Finalizer return Boolean;
324    --  Determine whether the current unit has at least one library-level
325    --  finalizer.
326
327    function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean;
328    --  Compare linker options, when sorting, first according to
329    --  Is_Internal_File (internal files come later) and then by
330    --  elaboration order position (latest to earliest).
331
332    procedure Move_Linker_Option (From : Natural; To : Natural);
333    --  Move routine for sorting linker options
334
335    procedure Resolve_Binder_Options;
336    --  Set the value of With_GNARL and With_DECGNAT. The latter only on VMS
337    --  since it tests for a package named "dec" which might cause a conflict
338    --  on non-VMS systems.
339
340    procedure Set_Char (C : Character);
341    --  Set given character in Statement_Buffer at the Last + 1 position
342    --  and increment Last by one to reflect the stored character.
343
344    procedure Set_Int (N : Int);
345    --  Set given value in decimal in Statement_Buffer with no spaces
346    --  starting at the Last + 1 position, and updating Last past the value.
347    --  A minus sign is output for a negative value.
348
349    procedure Set_Boolean (B : Boolean);
350    --  Set given boolean value in Statement_Buffer at the Last + 1 position
351    --  and update Last past the value.
352
353    procedure Set_IS_Pragma_Table;
354    --  Initializes contents of IS_Pragma_Settings table from ALI table
355
356    procedure Set_Main_Program_Name;
357    --  Given the main program name in Name_Buffer (length in Name_Len)
358    --  generate the name of the routine to be used in the call. The name
359    --  is generated starting at Last + 1, and Last is updated past it.
360
361    procedure Set_Name_Buffer;
362    --  Set the value stored in positions 1 .. Name_Len of the Name_Buffer
363
364    procedure Set_PSD_Pragma_Table;
365    --  Initializes contents of PSD_Pragma_Settings table from ALI table
366
367    procedure Set_String (S : String);
368    --  Sets characters of given string in Statement_Buffer, starting at the
369    --  Last + 1 position, and updating last past the string value.
370
371    procedure Set_String_Replace (S : String);
372    --  Replaces the last S'Length characters in the Statement_Buffer with
373    --  the characters of S. The caller must ensure that these characters do
374    --  in fact exist in the Statement_Buffer.
375
376    type Qualification_Mode is (Dollar_Sign, Dot, Double_Underscores);
377
378    procedure Set_Unit_Name (Mode : Qualification_Mode := Double_Underscores);
379    --  Given a unit name in the Name_Buffer, copy it into Statement_Buffer,
380    --  starting at the Last + 1 position and update Last past the value.
381    --  Depending on parameter Mode, a dot (.) can be qualified into double
382    --  underscores (__), a dollar sign ($) or left as is.
383
384    procedure Set_Unit_Number (U : Unit_Id);
385    --  Sets unit number (first unit is 1, leading zeroes output to line
386    --  up all output unit numbers nicely as required by the value, and
387    --  by the total number of units.
388
389    procedure Write_Info_Ada_C (Ada : String; C : String; Common : String);
390    --  For C code case, write C & Common, for Ada case write Ada & Common
391    --  to current binder output file using Write_Binder_Info.
392
393    procedure Write_Statement_Buffer;
394    --  Write out contents of statement buffer up to Last, and reset Last to 0
395
396    procedure Write_Statement_Buffer (S : String);
397    --  First writes its argument (using Set_String (S)), then writes out the
398    --  contents of statement buffer up to Last, and reset Last to 0
399
400    ------------------------------------
401    -- Check_System_Restrictions_Used --
402    ------------------------------------
403
404    procedure Check_System_Restrictions_Used is
405    begin
406       for J in Units.First .. Units.Last loop
407          if Get_Name_String (Units.Table (J).Sfile) = "s-restri.ads" then
408             System_Restrictions_Used := True;
409             return;
410          end if;
411       end loop;
412
413       System_Restrictions_Used := False;
414    end Check_System_Restrictions_Used;
415
416    ----------------------
417    -- Gen_Adafinal_Ada --
418    ----------------------
419
420    procedure Gen_Adafinal_Ada is
421    begin
422       WBI ("   procedure " & Ada_Final_Name.all & " is");
423
424       --  Do nothing if finalization is disabled
425
426       if Cumulative_Restrictions.Set (No_Finalization) then
427          WBI ("   begin");
428          WBI ("      null;");
429
430       --  General case
431
432       elsif VM_Target = No_VM then
433          WBI ("      procedure s_stalib_adafinal;");
434          WBI ("      pragma Import (C, s_stalib_adafinal, " &
435               """system__standard_library__adafinal"");");
436          WBI ("   begin");
437          WBI ("      s_stalib_adafinal;");
438
439       --  Pragma Import C cannot be used on virtual machine targets, therefore
440       --  call the runtime finalization routine directly.
441
442       else
443          WBI ("   begin");
444          WBI ("      System.Standard_Library.Adafinal;");
445       end if;
446
447       WBI ("   end " & Ada_Final_Name.all & ";");
448       WBI ("");
449    end Gen_Adafinal_Ada;
450
451    --------------------
452    -- Gen_Adafinal_C --
453    --------------------
454
455    procedure Gen_Adafinal_C is
456    begin
457       WBI ("void " & Ada_Final_Name.all & " (void) {");
458       WBI ("   system__standard_library__adafinal ();");
459       WBI ("}");
460       WBI ("");
461    end Gen_Adafinal_C;
462
463    ---------------------
464    -- Gen_Adainit_Ada --
465    ---------------------
466
467    procedure Gen_Adainit_Ada is
468       Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
469       Main_CPU      : Int renames ALIs.Table (ALIs.First).Main_CPU;
470
471    begin
472       WBI ("   procedure " & Ada_Init_Name.all & " is");
473
474       --  Generate externals for elaboration entities
475
476       for E in Elab_Order.First .. Elab_Order.Last loop
477          declare
478             Unum : constant Unit_Id := Elab_Order.Table (E);
479             U    : Unit_Record renames Units.Table (Unum);
480
481          begin
482             --  Check for Elab_Entity to be set for this unit
483
484             if U.Set_Elab_Entity
485
486             --  Don't generate reference for stand alone library
487
488               and then not U.SAL_Interface
489
490             --  Don't generate reference for predefined file in No_Run_Time
491             --  mode, since we don't include the object files in this case
492
493               and then not
494                 (No_Run_Time_Mode
495                    and then Is_Predefined_File_Name (U.Sfile))
496             then
497                Set_String ("      ");
498                Set_String ("E");
499                Set_Unit_Number (Unum);
500
501                case VM_Target is
502                   when No_VM | JVM_Target =>
503                      Set_String (" : Boolean; pragma Import (Ada, ");
504                   when CLI_Target =>
505                      Set_String (" : Boolean; pragma Import (CIL, ");
506                end case;
507
508                Set_String ("E");
509                Set_Unit_Number (Unum);
510                Set_String (", """);
511                Get_Name_String (U.Uname);
512
513                --  In the case of JGNAT we need to emit an Import name that
514                --  includes the class name (using '$' separators in the case
515                --  of a child unit name).
516
517                if VM_Target /= No_VM then
518                   for J in 1 .. Name_Len - 2 loop
519                      if VM_Target = CLI_Target
520                        or else Name_Buffer (J) /= '.'
521                      then
522                         Set_Char (Name_Buffer (J));
523                      else
524                         Set_String ("$");
525                      end if;
526                   end loop;
527
528                   if VM_Target /= CLI_Target or else U.Unit_Kind = 's' then
529                      Set_String (".");
530                   else
531                      Set_String ("_pkg.");
532                   end if;
533
534                   --  If the unit name is very long, then split the
535                   --  Import link name across lines using "&" (occurs
536                   --  in some C2 tests).
537
538                   if 2 * Name_Len + 60 > Hostparm.Max_Line_Length then
539                      Set_String (""" &");
540                      Write_Statement_Buffer;
541                      Set_String ("         """);
542                   end if;
543                end if;
544
545                Set_Unit_Name;
546                Set_String ("_E"");");
547                Write_Statement_Buffer;
548             end if;
549          end;
550       end loop;
551
552       Write_Statement_Buffer;
553
554       --  If the standard library is suppressed, then the only global variables
555       --  that might be needed (by the Ravenscar profile) are the priority and
556       --  the processor for the environment task.
557
558       if Suppress_Standard_Library_On_Target then
559          if Main_Priority /= No_Main_Priority then
560             WBI ("      Main_Priority : Integer;");
561             WBI ("      pragma Import (C, Main_Priority," &
562                  " ""__gl_main_priority"");");
563             WBI ("");
564          end if;
565
566          if Main_CPU /= No_Main_CPU then
567             WBI ("      Main_CPU : Integer;");
568             WBI ("      pragma Import (C, Main_CPU," &
569                  " ""__gl_main_cpu"");");
570             WBI ("");
571          end if;
572
573          WBI ("   begin");
574
575          if Main_Priority /= No_Main_Priority then
576             Set_String ("      Main_Priority := ");
577             Set_Int    (Main_Priority);
578             Set_Char   (';');
579             Write_Statement_Buffer;
580          end if;
581
582          if Main_CPU /= No_Main_CPU then
583             Set_String ("      Main_CPU := ");
584             Set_Int    (Main_CPU);
585             Set_Char   (';');
586             Write_Statement_Buffer;
587          end if;
588
589          if Main_Priority = No_Main_Priority
590            and then Main_CPU = No_Main_CPU
591          then
592             WBI ("      null;");
593          end if;
594
595       --  Normal case (standard library not suppressed). Set all global values
596       --  used by the run time.
597
598       else
599          WBI ("      Main_Priority : Integer;");
600          WBI ("      pragma Import (C, Main_Priority, " &
601               """__gl_main_priority"");");
602          WBI ("      Time_Slice_Value : Integer;");
603          WBI ("      pragma Import (C, Time_Slice_Value, " &
604               """__gl_time_slice_val"");");
605          WBI ("      WC_Encoding : Character;");
606          WBI ("      pragma Import (C, WC_Encoding, ""__gl_wc_encoding"");");
607          WBI ("      Locking_Policy : Character;");
608          WBI ("      pragma Import (C, Locking_Policy, " &
609               """__gl_locking_policy"");");
610          WBI ("      Queuing_Policy : Character;");
611          WBI ("      pragma Import (C, Queuing_Policy, " &
612               """__gl_queuing_policy"");");
613          WBI ("      Task_Dispatching_Policy : Character;");
614          WBI ("      pragma Import (C, Task_Dispatching_Policy, " &
615               """__gl_task_dispatching_policy"");");
616          WBI ("      Priority_Specific_Dispatching : System.Address;");
617          WBI ("      pragma Import (C, Priority_Specific_Dispatching, " &
618               """__gl_priority_specific_dispatching"");");
619          WBI ("      Num_Specific_Dispatching : Integer;");
620          WBI ("      pragma Import (C, Num_Specific_Dispatching, " &
621               """__gl_num_specific_dispatching"");");
622          WBI ("      Main_CPU : Integer;");
623          WBI ("      pragma Import (C, Main_CPU, " &
624               """__gl_main_cpu"");");
625
626          WBI ("      Interrupt_States : System.Address;");
627          WBI ("      pragma Import (C, Interrupt_States, " &
628               """__gl_interrupt_states"");");
629          WBI ("      Num_Interrupt_States : Integer;");
630          WBI ("      pragma Import (C, Num_Interrupt_States, " &
631               """__gl_num_interrupt_states"");");
632          WBI ("      Unreserve_All_Interrupts : Integer;");
633          WBI ("      pragma Import (C, Unreserve_All_Interrupts, " &
634               """__gl_unreserve_all_interrupts"");");
635
636          if Exception_Tracebacks then
637             WBI ("      Exception_Tracebacks : Integer;");
638             WBI ("      pragma Import (C, Exception_Tracebacks, " &
639                  """__gl_exception_tracebacks"");");
640          end if;
641
642          WBI ("      Zero_Cost_Exceptions : Integer;");
643          WBI ("      pragma Import (C, Zero_Cost_Exceptions, " &
644               """__gl_zero_cost_exceptions"");");
645          WBI ("      Detect_Blocking : Integer;");
646          WBI ("      pragma Import (C, Detect_Blocking, " &
647               """__gl_detect_blocking"");");
648          WBI ("      Default_Stack_Size : Integer;");
649          WBI ("      pragma Import (C, Default_Stack_Size, " &
650               """__gl_default_stack_size"");");
651          WBI ("      Leap_Seconds_Support : Integer;");
652          WBI ("      pragma Import (C, Leap_Seconds_Support, " &
653               """__gl_leap_seconds_support"");");
654
655          --  Import entry point for elaboration time signal handler
656          --  installation, and indication of if it's been called previously.
657
658          WBI ("");
659          WBI ("      procedure Install_Handler;");
660          WBI ("      pragma Import (C, Install_Handler, " &
661               """__gnat_install_handler"");");
662          WBI ("");
663          WBI ("      Handler_Installed : Integer;");
664          WBI ("      pragma Import (C, Handler_Installed, " &
665               """__gnat_handler_installed"");");
666
667          --  The import of the soft link which performs library-level object
668          --  finalization is not needed for VM targets; regular Ada is used in
669          --  that case. For restricted run-time libraries (ZFP and Ravenscar)
670          --  tasks are non-terminating, so we do not want finalization.
671
672          if VM_Target = No_VM and then not Configurable_Run_Time_On_Target then
673             WBI ("");
674             WBI ("      type No_Param_Proc is access procedure;");
675             WBI ("      Finalize_Library_Objects : No_Param_Proc;");
676             WBI ("      pragma Import (C, Finalize_Library_Objects, " &
677                  """__gnat_finalize_library_objects"");");
678          end if;
679
680          --  Import entry point for environment feature enable/disable
681          --  routine, and indication that it's been called previously.
682
683          if OpenVMS_On_Target then
684             WBI ("");
685             WBI ("      procedure Set_Features;");
686             WBI ("      pragma Import (C, Set_Features, " &
687                  """__gnat_set_features"");");
688             WBI ("");
689             WBI ("      Features_Set : Integer;");
690             WBI ("      pragma Import (C, Features_Set, " &
691                  """__gnat_features_set"");");
692
693             if Opt.Heap_Size /= 0 then
694                WBI ("");
695                WBI ("      Heap_Size : Integer;");
696                WBI ("      pragma Import (C, Heap_Size, " &
697                     """__gl_heap_size"");");
698
699                Write_Statement_Buffer;
700             end if;
701          end if;
702
703          --  Initialize stack limit variable of the environment task if the
704          --  stack check method is stack limit and stack check is enabled.
705
706          if Stack_Check_Limits_On_Target
707            and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
708          then
709             WBI ("");
710             WBI ("      procedure Initialize_Stack_Limit;");
711             WBI ("      pragma Import (C, Initialize_Stack_Limit, " &
712                  """__gnat_initialize_stack_limit"");");
713          end if;
714
715          --  Special processing when main program is CIL function/procedure
716
717          if VM_Target = CLI_Target
718            and then Bind_Main_Program
719            and then not No_Main_Subprogram
720          then
721             WBI ("");
722
723             --  Function case, use Set_Exit_Status to report the returned
724             --  status code, since that is the only mechanism available.
725
726             if ALIs.Table (ALIs.First).Main_Program = Func then
727                WBI ("      Result : Integer;");
728                WBI ("      procedure Set_Exit_Status (Code : Integer);");
729                WBI ("      pragma Import (C, Set_Exit_Status, " &
730                     """__gnat_set_exit_status"");");
731                WBI ("");
732                WBI ("      function Ada_Main_Program return Integer;");
733
734             --  Procedure case
735
736             else
737                WBI ("      procedure Ada_Main_Program;");
738             end if;
739
740             Get_Name_String (Units.Table (First_Unit_Entry).Uname);
741             Name_Len := Name_Len - 2;
742             WBI ("      pragma Import (CIL, Ada_Main_Program, """
743                  & Name_Buffer (1 .. Name_Len) & "."
744                  & Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len)) & """);");
745          end if;
746
747          WBI ("   begin");
748
749          Set_String ("      Main_Priority := ");
750          Set_Int    (Main_Priority);
751          Set_Char   (';');
752          Write_Statement_Buffer;
753
754          Set_String ("      Time_Slice_Value := ");
755
756          if Task_Dispatching_Policy_Specified = 'F'
757            and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
758          then
759             Set_Int (0);
760          else
761             Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
762          end if;
763
764          Set_Char   (';');
765          Write_Statement_Buffer;
766
767          Set_String ("      WC_Encoding := '");
768          Set_Char   (Get_WC_Encoding);
769
770          Set_String ("';");
771          Write_Statement_Buffer;
772
773          Set_String ("      Locking_Policy := '");
774          Set_Char   (Locking_Policy_Specified);
775          Set_String ("';");
776          Write_Statement_Buffer;
777
778          Set_String ("      Queuing_Policy := '");
779          Set_Char   (Queuing_Policy_Specified);
780          Set_String ("';");
781          Write_Statement_Buffer;
782
783          Set_String ("      Task_Dispatching_Policy := '");
784          Set_Char   (Task_Dispatching_Policy_Specified);
785          Set_String ("';");
786          Write_Statement_Buffer;
787
788          Gen_Restrictions_Ada;
789
790          WBI ("      Priority_Specific_Dispatching :=");
791          WBI ("        Local_Priority_Specific_Dispatching'Address;");
792
793          Set_String ("      Num_Specific_Dispatching := ");
794          Set_Int (PSD_Pragma_Settings.Last + 1);
795          Set_Char (';');
796          Write_Statement_Buffer;
797
798          Set_String ("      Main_CPU := ");
799          Set_Int    (Main_CPU);
800          Set_Char   (';');
801          Write_Statement_Buffer;
802
803          WBI ("      Interrupt_States := Local_Interrupt_States'Address;");
804
805          Set_String ("      Num_Interrupt_States := ");
806          Set_Int (IS_Pragma_Settings.Last + 1);
807          Set_Char (';');
808          Write_Statement_Buffer;
809
810          Set_String ("      Unreserve_All_Interrupts := ");
811
812          if Unreserve_All_Interrupts_Specified then
813             Set_String ("1");
814          else
815             Set_String ("0");
816          end if;
817
818          Set_Char (';');
819          Write_Statement_Buffer;
820
821          if Exception_Tracebacks then
822             WBI ("      Exception_Tracebacks := 1;");
823          end if;
824
825          Set_String ("      Zero_Cost_Exceptions := ");
826
827          if Zero_Cost_Exceptions_Specified then
828             Set_String ("1");
829          else
830             Set_String ("0");
831          end if;
832
833          Set_String (";");
834          Write_Statement_Buffer;
835
836          Set_String ("      Detect_Blocking := ");
837
838          if Detect_Blocking then
839             Set_Int (1);
840          else
841             Set_Int (0);
842          end if;
843
844          Set_String (";");
845          Write_Statement_Buffer;
846
847          Set_String ("      Default_Stack_Size := ");
848          Set_Int (Default_Stack_Size);
849          Set_String (";");
850          Write_Statement_Buffer;
851
852          Set_String ("      Leap_Seconds_Support := ");
853
854          if Leap_Seconds_Support then
855             Set_Int (1);
856          else
857             Set_Int (0);
858          end if;
859
860          Set_String (";");
861          Write_Statement_Buffer;
862
863          --  Generate call to Install_Handler
864
865          --  In .NET, when binding with -z, we don't install the signal handler
866          --  to let the caller handle the last exception handler.
867
868          if VM_Target /= CLI_Target
869            or else Bind_Main_Program
870          then
871             WBI ("");
872             WBI ("      if Handler_Installed = 0 then");
873             WBI ("         Install_Handler;");
874             WBI ("      end if;");
875          end if;
876
877          --  Generate call to Set_Features
878
879          if OpenVMS_On_Target then
880             WBI ("");
881             WBI ("      if Features_Set = 0 then");
882             WBI ("         Set_Features;");
883             WBI ("      end if;");
884
885             --  Features_Set may twiddle the heap size according to a logical
886             --  name, but the binder switch must override.
887
888             if Opt.Heap_Size /= 0 then
889                Set_String ("      Heap_Size := ");
890                Set_Int (Opt.Heap_Size);
891                Set_Char   (';');
892                Write_Statement_Buffer;
893             end if;
894          end if;
895       end if;
896
897       --  Generate call to set Initialize_Scalar values if active
898
899       if Initialize_Scalars_Used then
900          WBI ("");
901          Set_String ("      System.Scalar_Values.Initialize ('");
902          Set_Char (Initialize_Scalars_Mode1);
903          Set_String ("', '");
904          Set_Char (Initialize_Scalars_Mode2);
905          Set_String ("');");
906          Write_Statement_Buffer;
907       end if;
908
909       --  Generate assignment of default secondary stack size if set
910
911       if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
912          WBI ("");
913          Set_String ("      System.Secondary_Stack.");
914          Set_String ("Default_Secondary_Stack_Size := ");
915          Set_Int (Opt.Default_Sec_Stack_Size);
916          Set_Char (';');
917          Write_Statement_Buffer;
918       end if;
919
920       --  Initialize stack limit variable of the environment task if the
921       --  stack check method is stack limit and stack check is enabled.
922
923       if Stack_Check_Limits_On_Target
924         and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
925       then
926          WBI ("");
927          WBI ("      Initialize_Stack_Limit;");
928       end if;
929
930       --  Attach Finalize_Library to the right soft link. Do it only when not
931       --  using a restricted run time, in which case tasks are
932       --  non-terminating, so we do not want library-level finalization.
933
934       if not Configurable_Run_Time_On_Target then
935          if not Suppress_Standard_Library_On_Target then
936             WBI ("");
937
938             if VM_Target = No_VM then
939                if Lib_Final_Built then
940                   Set_String ("      Finalize_Library_Objects := ");
941                   Set_String ("Finalize_Library'access;");
942                else
943                   Set_String ("      Finalize_Library_Objects := null;");
944                end if;
945
946             --  On VM targets use regular Ada to set the soft link
947
948             else
949                if Lib_Final_Built then
950                   Set_String
951                     ("      System.Soft_Links.Finalize_Library_Objects");
952                   Set_String (" := Finalize_Library'access;");
953                else
954                   Set_String
955                     ("      System.Soft_Links.Finalize_Library_Objects");
956                   Set_String (" := null;");
957                end if;
958             end if;
959
960             Write_Statement_Buffer;
961          end if;
962       end if;
963
964       --  Generate elaboration calls
965
966       WBI ("");
967       Gen_Elab_Calls_Ada;
968
969       --  Case of main program is CIL function or procedure
970
971       if VM_Target = CLI_Target
972         and then Bind_Main_Program
973         and then not No_Main_Subprogram
974       then
975          --  For function case, use Set_Exit_Status to set result
976
977          if ALIs.Table (ALIs.First).Main_Program = Func then
978             WBI ("      Result := Ada_Main_Program;");
979             WBI ("      Set_Exit_Status (Result);");
980
981          --  Procedure case
982
983          else
984             WBI ("      Ada_Main_Program;");
985          end if;
986       end if;
987
988       WBI ("   end " & Ada_Init_Name.all & ";");
989       WBI ("");
990    end Gen_Adainit_Ada;
991
992    -------------------
993    -- Gen_Adainit_C --
994    --------------------
995
996    procedure Gen_Adainit_C is
997       Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
998       Main_CPU      : Int renames ALIs.Table (ALIs.First).Main_CPU;
999
1000    begin
1001       WBI ("void " & Ada_Init_Name.all & " (void)");
1002       WBI ("{");
1003
1004       --  Generate externals for elaboration entities
1005
1006       for E in Elab_Order.First .. Elab_Order.Last loop
1007          declare
1008             Unum : constant Unit_Id := Elab_Order.Table (E);
1009             U    : Unit_Record renames Units.Table (Unum);
1010
1011          begin
1012             --  Check for Elab entity to be set for this unit
1013
1014             if U.Set_Elab_Entity
1015
1016             --  Don't generate reference for stand alone library
1017
1018               and then not U.SAL_Interface
1019
1020             --  Don't generate reference for predefined file in No_Run_Time
1021             --  mode, since we don't include the object files in this case
1022
1023               and then not
1024                 (No_Run_Time_Mode
1025                    and then Is_Predefined_File_Name (U.Sfile))
1026             then
1027                Set_String ("   extern char ");
1028                Get_Name_String (U.Uname);
1029                Set_Unit_Name;
1030                Set_String ("_E;");
1031                Write_Statement_Buffer;
1032             end if;
1033          end;
1034       end loop;
1035
1036       Write_Statement_Buffer;
1037
1038       --  Standard library suppressed
1039
1040       if Suppress_Standard_Library_On_Target then
1041
1042          --  Case of High_Integrity_Mode mode. Set __gl_main_priority and
1043          --  __gl_main_cpu if needed for the Ravenscar profile.
1044
1045          if Main_Priority /= No_Main_Priority then
1046             WBI ("   extern int __gl_main_priority;");
1047             Set_String ("   __gl_main_priority = ");
1048             Set_Int    (Main_Priority);
1049             Set_Char   (';');
1050             Write_Statement_Buffer;
1051          end if;
1052
1053          if Main_CPU /= No_Main_CPU then
1054             WBI ("   extern int __gl_main_cpu;");
1055             Set_String ("   __gl_main_cpu = ");
1056             Set_Int    (Main_CPU);
1057             Set_Char   (';');
1058             Write_Statement_Buffer;
1059          end if;
1060
1061       --  Normal case (standard library not suppressed)
1062
1063       else
1064          --  Generate definition for interrupt states string
1065
1066          Set_String ("   static const char *local_interrupt_states = """);
1067
1068          for J in 0 .. IS_Pragma_Settings.Last loop
1069             Set_Char (IS_Pragma_Settings.Table (J));
1070          end loop;
1071
1072          Set_String (""";");
1073          Write_Statement_Buffer;
1074
1075          --  Generate definition for priority specific dispatching string
1076
1077          Set_String
1078            ("   static const char *local_priority_specific_dispatching = """);
1079
1080          for J in 0 .. PSD_Pragma_Settings.Last loop
1081             Set_Char (PSD_Pragma_Settings.Table (J));
1082          end loop;
1083
1084          Set_String (""";");
1085          Write_Statement_Buffer;
1086
1087          --  Generate declaration for secondary stack default if needed
1088
1089          if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
1090             WBI ("   extern int system__secondary_stack__" &
1091                  "default_secondary_stack_size;");
1092          end if;
1093
1094          WBI ("");
1095
1096          --  Code for normal case (standard library not suppressed)
1097
1098          --  We call the routine from inside adainit() because this works for
1099          --  both programs with and without binder generated "main" functions.
1100
1101          WBI ("   extern int __gl_main_priority;");
1102          Set_String ("   __gl_main_priority = ");
1103          Set_Int (Main_Priority);
1104          Set_Char (';');
1105          Write_Statement_Buffer;
1106
1107          WBI ("   extern int __gl_time_slice_val;");
1108          Set_String ("   __gl_time_slice_val = ");
1109
1110          if Task_Dispatching_Policy = 'F'
1111            and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
1112          then
1113             Set_Int (0);
1114          else
1115             Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
1116          end if;
1117
1118          Set_Char   (';');
1119          Write_Statement_Buffer;
1120
1121          WBI ("   extern char __gl_wc_encoding;");
1122          Set_String ("   __gl_wc_encoding = '");
1123          Set_Char (Get_WC_Encoding);
1124
1125          Set_String ("';");
1126          Write_Statement_Buffer;
1127
1128          WBI ("   extern char __gl_locking_policy;");
1129          Set_String ("   __gl_locking_policy = '");
1130          Set_Char (Locking_Policy_Specified);
1131          Set_String ("';");
1132          Write_Statement_Buffer;
1133
1134          WBI ("   extern char __gl_queuing_policy;");
1135          Set_String ("   __gl_queuing_policy = '");
1136          Set_Char (Queuing_Policy_Specified);
1137          Set_String ("';");
1138          Write_Statement_Buffer;
1139
1140          WBI ("   extern char __gl_task_dispatching_policy;");
1141          Set_String ("   __gl_task_dispatching_policy = '");
1142          Set_Char (Task_Dispatching_Policy_Specified);
1143          Set_String ("';");
1144          Write_Statement_Buffer;
1145
1146          WBI ("   extern int __gl_main_cpu;");
1147          Set_String ("   __gl_main_cpu = ");
1148          Set_Int (Main_CPU);
1149          Set_Char (';');
1150          Write_Statement_Buffer;
1151
1152          Gen_Restrictions_C;
1153
1154          WBI ("   extern const void *__gl_interrupt_states;");
1155          WBI ("   __gl_interrupt_states = local_interrupt_states;");
1156
1157          WBI ("   extern int __gl_num_interrupt_states;");
1158          Set_String ("   __gl_num_interrupt_states = ");
1159          Set_Int (IS_Pragma_Settings.Last + 1);
1160          Set_String (";");
1161          Write_Statement_Buffer;
1162
1163          WBI ("   extern const void *__gl_priority_specific_dispatching;");
1164          WBI ("   __gl_priority_specific_dispatching =" &
1165               " local_priority_specific_dispatching;");
1166
1167          WBI ("   extern int __gl_num_specific_dispatching;");
1168          Set_String ("   __gl_num_specific_dispatching = ");
1169          Set_Int (PSD_Pragma_Settings.Last + 1);
1170          Set_String (";");
1171          Write_Statement_Buffer;
1172
1173          WBI ("   extern int __gl_unreserve_all_interrupts;");
1174          Set_String ("   __gl_unreserve_all_interrupts = ");
1175          Set_Int    (Boolean'Pos (Unreserve_All_Interrupts_Specified));
1176          Set_String (";");
1177          Write_Statement_Buffer;
1178
1179          if Exception_Tracebacks then
1180             WBI ("   extern int __gl_exception_tracebacks;");
1181             WBI ("   __gl_exception_tracebacks = 1;");
1182          end if;
1183
1184          WBI ("   extern int __gl_zero_cost_exceptions;");
1185          Set_String ("   __gl_zero_cost_exceptions = ");
1186          Set_Int    (Boolean'Pos (Zero_Cost_Exceptions_Specified));
1187          Set_String (";");
1188          Write_Statement_Buffer;
1189
1190          WBI ("   extern int __gl_detect_blocking;");
1191          Set_String ("   __gl_detect_blocking = ");
1192
1193          if Detect_Blocking then
1194             Set_Int (1);
1195          else
1196             Set_Int (0);
1197          end if;
1198
1199          Set_String (";");
1200          Write_Statement_Buffer;
1201
1202          WBI ("   extern int __gl_default_stack_size;");
1203          Set_String ("   __gl_default_stack_size = ");
1204          Set_Int    (Default_Stack_Size);
1205          Set_String (";");
1206          Write_Statement_Buffer;
1207
1208          WBI ("   extern int __gl_leap_seconds_support;");
1209          Set_String ("   __gl_leap_seconds_support = ");
1210
1211          if Leap_Seconds_Support then
1212             Set_Int (1);
1213          else
1214             Set_Int (0);
1215          end if;
1216
1217          Set_String (";");
1218          Write_Statement_Buffer;
1219
1220          WBI ("");
1221
1222          --  Install elaboration time signal handler
1223
1224          WBI ("   if (__gnat_handler_installed == 0)");
1225          WBI ("     {");
1226          WBI ("        __gnat_install_handler ();");
1227          WBI ("     }");
1228
1229          --  Call feature enable/disable routine
1230
1231          if OpenVMS_On_Target then
1232             WBI ("   if (__gnat_features_set == 0)");
1233             WBI ("     {");
1234             WBI ("        __gnat_set_features ();");
1235             WBI ("     }");
1236          end if;
1237       end if;
1238
1239       --  Initialize stack limit for the environment task if the stack
1240       --  check method is stack limit and stack check is enabled.
1241
1242       if Stack_Check_Limits_On_Target
1243         and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
1244       then
1245          WBI ("");
1246          WBI ("   __gnat_initialize_stack_limit ();");
1247       end if;
1248
1249       --  Generate call to set Initialize_Scalar values if needed
1250
1251       if Initialize_Scalars_Used then
1252          WBI ("");
1253          Set_String ("      system__scalar_values__initialize('");
1254          Set_Char (Initialize_Scalars_Mode1);
1255          Set_String ("', '");
1256          Set_Char (Initialize_Scalars_Mode2);
1257          Set_String ("');");
1258          Write_Statement_Buffer;
1259       end if;
1260
1261       --  Generate assignment of default secondary stack size if set
1262
1263       if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
1264          WBI ("");
1265          Set_String ("   system__secondary_stack__");
1266          Set_String ("default_secondary_stack_size = ");
1267          Set_Int (Opt.Default_Sec_Stack_Size);
1268          Set_Char (';');
1269          Write_Statement_Buffer;
1270       end if;
1271
1272       --  Generate elaboration calls
1273
1274       WBI ("");
1275       Gen_Elab_Calls_C;
1276       WBI ("}");
1277       WBI ("");
1278    end Gen_Adainit_C;
1279
1280    ------------------------
1281    -- Gen_Elab_Calls_Ada --
1282    ------------------------
1283
1284    procedure Gen_Elab_Calls_Ada is
1285    begin
1286       for E in Elab_Order.First .. Elab_Order.Last loop
1287          declare
1288             Unum : constant Unit_Id := Elab_Order.Table (E);
1289             U    : Unit_Record renames Units.Table (Unum);
1290
1291             Unum_Spec : Unit_Id;
1292             --  This is the unit number of the spec that corresponds to
1293             --  this entry. It is the same as Unum except when the body
1294             --  and spec are different and we are currently processing
1295             --  the body, in which case it is the spec (Unum + 1).
1296
1297          begin
1298             if U.Utype = Is_Body then
1299                Unum_Spec := Unum + 1;
1300             else
1301                Unum_Spec := Unum;
1302             end if;
1303
1304             --  Nothing to do if predefined unit in no run time mode
1305
1306             if No_Run_Time_Mode and then Is_Predefined_File_Name (U.Sfile) then
1307                null;
1308
1309             --  Case of no elaboration code
1310
1311             elsif U.No_Elab then
1312
1313                --  The only case in which we have to do something is if
1314                --  this is a body, with a separate spec, where the separate
1315                --  spec has an elaboration entity defined.
1316
1317                --  In that case, this is where we set the elaboration entity
1318                --  to True, we do not need to test if this has already been
1319                --  done, since it is quicker to set the flag than to test it.
1320
1321                if not U.SAL_Interface and then U.Utype = Is_Body
1322                  and then Units.Table (Unum_Spec).Set_Elab_Entity
1323                then
1324                   Set_String ("      E");
1325                   Set_Unit_Number (Unum_Spec);
1326                   Set_String (" := True;");
1327                   Write_Statement_Buffer;
1328                end if;
1329
1330             --  Here if elaboration code is present. If binding a library
1331             --  or if there is a non-Ada main subprogram then we generate:
1332
1333             --    if not uname_E then
1334             --       uname'elab_[spec|body];
1335             --       uname_E := True;
1336             --    end if;
1337
1338             --  Otherwise, elaboration routines are called unconditionally:
1339
1340             --    uname'elab_[spec|body];
1341             --    uname_E := True;
1342
1343             --  The uname_E assignment is skipped if this is a separate spec,
1344             --  since the assignment will be done when we process the body.
1345
1346             elsif not U.SAL_Interface then
1347                if Force_Checking_Of_Elaboration_Flags or
1348                   Interface_Library_Unit or
1349                   (not Bind_Main_Program)
1350                then
1351                   Set_String ("      if not E");
1352                   Set_Unit_Number (Unum_Spec);
1353                   Set_String (" then");
1354                   Write_Statement_Buffer;
1355                   Set_String ("   ");
1356                end if;
1357
1358                Set_String ("      ");
1359                Get_Decoded_Name_String_With_Brackets (U.Uname);
1360
1361                if VM_Target = CLI_Target and then U.Unit_Kind /= 's' then
1362                   if Name_Buffer (Name_Len) = 's' then
1363                      Name_Buffer (Name_Len - 1 .. Name_Len + 12) :=
1364                        "_pkg'elab_spec";
1365                   else
1366                      Name_Buffer (Name_Len - 1 .. Name_Len + 12) :=
1367                        "_pkg'elab_body";
1368                   end if;
1369
1370                   Name_Len := Name_Len + 12;
1371
1372                else
1373                   if Name_Buffer (Name_Len) = 's' then
1374                      Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1375                        "'elab_spec";
1376                   else
1377                      Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1378                        "'elab_body";
1379                   end if;
1380
1381                   Name_Len := Name_Len + 8;
1382                end if;
1383
1384                Set_Casing (U.Icasing);
1385                Set_Name_Buffer;
1386                Set_Char (';');
1387                Write_Statement_Buffer;
1388
1389                if U.Utype /= Is_Spec then
1390                   if Force_Checking_Of_Elaboration_Flags or
1391                      Interface_Library_Unit or
1392                      (not Bind_Main_Program)
1393                   then
1394                      Set_String ("   ");
1395                   end if;
1396
1397                   Set_String ("      E");
1398                   Set_Unit_Number (Unum_Spec);
1399                   Set_String (" := True;");
1400                   Write_Statement_Buffer;
1401                end if;
1402
1403                if Force_Checking_Of_Elaboration_Flags or
1404                   Interface_Library_Unit or
1405                   (not Bind_Main_Program)
1406                then
1407                   WBI ("      end if;");
1408                end if;
1409             end if;
1410          end;
1411       end loop;
1412    end Gen_Elab_Calls_Ada;
1413
1414    ----------------------
1415    -- Gen_Elab_Calls_C --
1416    ----------------------
1417
1418    procedure Gen_Elab_Calls_C is
1419    begin
1420       for E in Elab_Order.First .. Elab_Order.Last loop
1421          declare
1422             Unum : constant Unit_Id := Elab_Order.Table (E);
1423             U    : Unit_Record renames Units.Table (Unum);
1424
1425             Unum_Spec : Unit_Id;
1426             --  This is the unit number of the spec that corresponds to
1427             --  this entry. It is the same as Unum except when the body
1428             --  and spec are different and we are currently processing
1429             --  the body, in which case it is the spec (Unum + 1).
1430
1431          begin
1432             if U.Utype = Is_Body then
1433                Unum_Spec := Unum + 1;
1434             else
1435                Unum_Spec := Unum;
1436             end if;
1437
1438             --  Nothing to do if predefined unit in no run time mode
1439
1440             if No_Run_Time_Mode and then Is_Predefined_File_Name (U.Sfile) then
1441                null;
1442
1443             --  Case of no elaboration code
1444
1445             elsif U.No_Elab then
1446
1447                --  The only case in which we have to do something is if
1448                --  this is a body, with a separate spec, where the separate
1449                --  spec has an elaboration entity defined.
1450
1451                --  In that case, this is where we set the elaboration entity
1452                --  to True, we do not need to test if this has already been
1453                --  done, since it is quicker to set the flag than to test it.
1454
1455                if not U.SAL_Interface and then U.Utype = Is_Body
1456                  and then Units.Table (Unum_Spec).Set_Elab_Entity
1457                then
1458                   Set_String ("   ");
1459                   Get_Name_String (U.Uname);
1460                   Set_Unit_Name;
1461                   Set_String ("_E = 1;");
1462                   Write_Statement_Buffer;
1463                end if;
1464
1465             --  Here if elaboration code is present. If binding a library
1466             --  or if there is a non-Ada main subprogram then we generate:
1467
1468             --    if (uname_E == 0) {
1469             --       uname__elab[s|b] ();
1470             --       uname_E++;
1471             --    }
1472
1473             --  The uname_E assignment is skipped if this is a separate spec,
1474             --  since the assignment will be done when we process the body.
1475
1476             elsif not U.SAL_Interface then
1477                Get_Name_String (U.Uname);
1478
1479                if Force_Checking_Of_Elaboration_Flags or
1480                   Interface_Library_Unit or
1481                   (not Bind_Main_Program)
1482                then
1483                   Set_String ("   if (");
1484                   Set_Unit_Name;
1485                   Set_String ("_E == 0) {");
1486                   Write_Statement_Buffer;
1487                   Set_String ("   ");
1488                end if;
1489
1490                Set_String ("   ");
1491                Set_Unit_Name;
1492                Set_String ("___elab");
1493                Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
1494                Set_String (" ();");
1495                Write_Statement_Buffer;
1496
1497                if U.Utype /= Is_Spec then
1498                   if Force_Checking_Of_Elaboration_Flags or
1499                      Interface_Library_Unit or
1500                      (not Bind_Main_Program)
1501                   then
1502                      Set_String ("   ");
1503                   end if;
1504
1505                   Set_String ("   ");
1506                   Set_Unit_Name;
1507                   Set_String ("_E++;");
1508                   Write_Statement_Buffer;
1509                end if;
1510
1511                if Force_Checking_Of_Elaboration_Flags or
1512                   Interface_Library_Unit or
1513                   (not Bind_Main_Program)
1514                then
1515                   WBI ("   }");
1516                end if;
1517             end if;
1518          end;
1519       end loop;
1520    end Gen_Elab_Calls_C;
1521
1522    ----------------------
1523    -- Gen_Elab_Defs_C --
1524    ----------------------
1525
1526    procedure Gen_Elab_Defs_C is
1527    begin
1528       WBI ("/* BEGIN ELABORATION DEFINITIONS */");
1529
1530       for E in Elab_Order.First .. Elab_Order.Last loop
1531
1532          --  Generate declaration of elaboration procedure if elaboration
1533          --  needed. Note that passive units are always excluded.
1534
1535          if not Units.Table (Elab_Order.Table (E)).No_Elab then
1536             Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
1537             Set_String ("extern void ");
1538             Set_Unit_Name;
1539             Set_String ("___elab");
1540             Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
1541             Set_String (" (void);");
1542             Write_Statement_Buffer;
1543          end if;
1544       end loop;
1545       WBI ("");
1546    end Gen_Elab_Defs_C;
1547
1548    ------------------------
1549    -- Gen_Elab_Order_Ada --
1550    ------------------------
1551
1552    procedure Gen_Elab_Order_Ada is
1553    begin
1554       WBI ("   --  BEGIN ELABORATION ORDER");
1555
1556       for J in Elab_Order.First .. Elab_Order.Last loop
1557          Set_String ("   --  ");
1558          Get_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
1559          Set_Name_Buffer;
1560          Write_Statement_Buffer;
1561       end loop;
1562
1563       WBI ("   --  END ELABORATION ORDER");
1564       WBI ("");
1565    end Gen_Elab_Order_Ada;
1566
1567    ----------------------
1568    -- Gen_Elab_Order_C --
1569    ----------------------
1570
1571    procedure Gen_Elab_Order_C is
1572    begin
1573       WBI ("/* BEGIN ELABORATION ORDER");
1574
1575       for J in Elab_Order.First .. Elab_Order.Last loop
1576          Get_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
1577          Set_Name_Buffer;
1578          Write_Statement_Buffer;
1579       end loop;
1580
1581       WBI ("   END ELABORATION ORDER */");
1582       WBI ("");
1583    end Gen_Elab_Order_C;
1584
1585    ------------------------------
1586    -- Gen_Finalize_Library_Ada --
1587    ------------------------------
1588
1589    procedure Gen_Finalize_Library_Ada is
1590       Count : Int := 1;
1591       U     : Unit_Record;
1592       Uspec : Unit_Record;
1593       Unum  : Unit_Id;
1594
1595    begin
1596       for E in reverse Elab_Order.First .. Elab_Order.Last loop
1597          Unum := Elab_Order.Table (E);
1598          U    := Units.Table (Unum);
1599
1600          --  We are only interested in non-generic packages
1601
1602          if U.Unit_Kind = 'p'
1603            and then U.Has_Finalizer
1604            and then not U.Is_Generic
1605            and then not U.No_Elab
1606          then
1607             if not Lib_Final_Built then
1608                Lib_Final_Built := True;
1609
1610                WBI ("   procedure Finalize_Library is");
1611
1612                --  The following flag is used to check for library-level
1613                --  exceptions raised during finalization. The symbol comes
1614                --  from System.Soft_Links. VM targets use regular Ada to
1615                --  reference the entity.
1616
1617                if VM_Target = No_VM then
1618                   WBI ("      LE_Set : Boolean;");
1619
1620                   Set_String ("      pragma Import (Ada, LE_Set, ");
1621                   Set_String ("""__gnat_library_exception_set"");");
1622                   Write_Statement_Buffer;
1623                end if;
1624
1625                WBI ("   begin");
1626             end if;
1627
1628             --  Generate:
1629             --    declare
1630             --       procedure F<Count>;
1631
1632             Set_String ("      declare");
1633             Write_Statement_Buffer;
1634
1635             Set_String ("         procedure F");
1636             Set_Int    (Count);
1637             Set_Char   (';');
1638             Write_Statement_Buffer;
1639
1640             --  Generate:
1641             --    pragma Import (CIL, F<Count>, "xx.yy_pkg.Finalize[B/S]");
1642             --    --  for .NET targets
1643
1644             --    pragma Import (Java, F<Count>, "xx$yy.Finalize[B/S]");
1645             --    --  for JVM targets
1646
1647             --    pragma Import (Ada, F<Count>, "xx__yy__Finalize[B/S]");
1648             --    --  for default targets
1649
1650             if VM_Target = CLI_Target then
1651                Set_String ("         pragma Import (CIL, F");
1652             elsif VM_Target = JVM_Target then
1653                Set_String ("         pragma Import (Java, F");
1654             else
1655                Set_String ("         pragma Import (Ada, F");
1656             end if;
1657
1658             Set_Int (Count);
1659             Set_String (", """);
1660
1661             --  Dealing with package bodies is a little complicated. In such
1662             --  cases we must retrieve the package spec since it contains the
1663             --  spec of the body finalizer.
1664
1665             if U.Utype = Is_Body then
1666                Unum  := Unum + 1;
1667                Uspec := Units.Table (Unum);
1668             else
1669                Uspec := U;
1670             end if;
1671
1672             Get_Name_String (Uspec.Uname);
1673
1674             --  Perform name construction
1675
1676             --  .NET   xx.yy_pkg.finalize
1677
1678             if VM_Target = CLI_Target then
1679                Set_Unit_Name (Mode => Dot);
1680                Set_String ("_pkg.finalize");
1681
1682             --  JVM   xx$yy.finalize
1683
1684             elsif VM_Target = JVM_Target then
1685                Set_Unit_Name (Mode => Dollar_Sign);
1686                Set_String (".finalize");
1687
1688             --  Default   xx__yy__finalize
1689
1690             else
1691                Set_Unit_Name;
1692                Set_String ("__finalize");
1693             end if;
1694
1695             --  Package spec processing
1696
1697             if U.Utype = Is_Spec
1698               or else U.Utype = Is_Spec_Only
1699             then
1700                Set_Char ('S');
1701
1702             --  Package body processing
1703
1704             else
1705                Set_Char ('B');
1706             end if;
1707
1708             Set_String (""");");
1709             Write_Statement_Buffer;
1710
1711             WBI ("      begin");
1712
1713             --  Generate:
1714             --       F<Count>;
1715             --    end;
1716
1717             Set_String ("         F");
1718             Set_Int    (Count);
1719             Set_Char   (';');
1720             Write_Statement_Buffer;
1721             WBI ("      end;");
1722
1723             Count := Count + 1;
1724          end if;
1725       end loop;
1726
1727       if Lib_Final_Built then
1728
1729          --  It is possible that the finalization of a library-level object
1730          --  raised an exception. In that case import the actual exception
1731          --  and the routine necessary to raise it.
1732
1733          if VM_Target = No_VM then
1734             WBI ("      if LE_Set then");
1735             WBI ("         declare");
1736             WBI ("            LE : Ada.Exceptions.Exception_Occurrence;");
1737
1738             Set_String ("            pragma Import (Ada, LE, ");
1739             Set_String ("""__gnat_library_exception"");");
1740             Write_Statement_Buffer;
1741
1742             Set_String ("            procedure Raise_Controlled ");
1743             Set_String ("(E : Ada.Exceptions.Exception_Occurrence);");
1744             Write_Statement_Buffer;
1745
1746             Set_String ("            pragma Import (Ada, Raise_Controlled, ");
1747             Set_String ("""__gnat_raise_from_controlled_operation"");");
1748             Write_Statement_Buffer;
1749
1750             WBI ("         begin");
1751             WBI ("            Raise_Controlled (LE);");
1752             WBI ("         end;");
1753
1754          --  VM-specific code, use regular Ada to produce the desired behavior
1755
1756          else
1757             WBI ("      if System.Soft_Links.Library_Exception_Set then");
1758
1759             Set_String ("         Ada.Exceptions.Reraise_Occurrence (");
1760             Set_String ("System.Soft_Links.Library_Exception);");
1761             Write_Statement_Buffer;
1762          end if;
1763
1764          WBI ("      end if;");
1765          WBI ("   end Finalize_Library;");
1766          WBI ("");
1767       end if;
1768    end Gen_Finalize_Library_Ada;
1769
1770    ----------------------------
1771    -- Gen_Finalize_Library_C --
1772    ----------------------------
1773
1774    procedure Gen_Finalize_Library_C is
1775       U     : Unit_Record;
1776       Uspec : Unit_Record;
1777       Unum  : Unit_Id;
1778
1779    begin
1780       WBI ("   /* BEGIN FINALIZE */");
1781
1782       for E in reverse Elab_Order.First .. Elab_Order.Last loop
1783          Unum := Elab_Order.Table (E);
1784          U    := Units.Table (Unum);
1785
1786          --  We are only interested in non-generic packages
1787
1788          if U.Unit_Kind = 'p'
1789            and then U.Has_Finalizer
1790            and then not U.Is_Generic
1791            and then not U.No_Elab
1792          then
1793             Set_String ("   ");
1794
1795             --  Dealing with package bodies is a little complicated. In such
1796             --  cases we must retrieve the package spec since it contains the
1797             --  spec of the body finalizer.
1798
1799             if U.Utype = Is_Body then
1800                Unum  := Unum + 1;
1801                Uspec := Units.Table (Unum);
1802             else
1803                Uspec := U;
1804             end if;
1805
1806             Get_Name_String (Uspec.Uname);
1807             Set_Unit_Name;
1808             Set_String ("__finalize");
1809
1810             --  Package spec processing
1811
1812             if U.Utype = Is_Spec
1813               or else U.Utype = Is_Spec_Only
1814             then
1815                Set_Char ('S');
1816
1817             --  Package body processing
1818
1819             else
1820                Set_Char ('B');
1821             end if;
1822
1823             Set_String (" ();");
1824
1825             Write_Statement_Buffer;
1826          end if;
1827       end loop;
1828
1829       WBI ("   /* END FINALIZE */");
1830       WBI ("");
1831    end Gen_Finalize_Library_C;
1832
1833    ---------------------------------
1834    -- Gen_Finalize_Library_Defs_C --
1835    ---------------------------------
1836
1837    procedure Gen_Finalize_Library_Defs_C is
1838       U     : Unit_Record;
1839       Uspec : Unit_Record;
1840       Unum  : Unit_Id;
1841
1842    begin
1843       WBI ("/* BEGIN FINALIZE DEFINITIONS */");
1844
1845       for E in reverse Elab_Order.First .. Elab_Order.Last loop
1846          Unum := Elab_Order.Table (E);
1847          U    := Units.Table (Unum);
1848
1849          --  We are only interested in non-generic packages
1850
1851          if U.Unit_Kind = 'p'
1852            and then U.Has_Finalizer
1853            and then not U.Is_Generic
1854            and then not U.No_Elab
1855          then
1856             --  Dealing with package bodies is a little complicated. In such
1857             --  cases we must retrieve the package spec since it contains the
1858             --  spec of the body finalizer.
1859
1860             if U.Utype = Is_Body then
1861                Unum  := Unum + 1;
1862                Uspec := Units.Table (Unum);
1863             else
1864                Uspec := U;
1865             end if;
1866
1867             Set_String ("extern void ");
1868             Get_Name_String (Uspec.Uname);
1869             Set_Unit_Name;
1870             Set_String ("__finalize");
1871
1872             if U.Utype = Is_Spec
1873               or else U.Utype = Is_Spec_Only
1874             then
1875                Set_Char ('S');
1876             else
1877                Set_Char ('B');
1878             end if;
1879
1880             Set_String (" (void);");
1881             Write_Statement_Buffer;
1882          end if;
1883       end loop;
1884
1885       WBI ("/* END FINALIZE DEFINITIONS */");
1886       WBI ("");
1887    end Gen_Finalize_Library_Defs_C;
1888
1889    ------------------
1890    -- Gen_Main_Ada --
1891    ------------------
1892
1893    procedure Gen_Main_Ada is
1894    begin
1895       if Exit_Status_Supported_On_Target then
1896          Set_String ("   function ");
1897       else
1898          Set_String ("   procedure ");
1899       end if;
1900
1901       Set_String (Get_Main_Name);
1902
1903       if Command_Line_Args_On_Target then
1904          Write_Statement_Buffer;
1905          WBI ("     (argc : Integer;");
1906          WBI ("      argv : System.Address;");
1907          WBI ("      envp : System.Address)");
1908
1909          if Exit_Status_Supported_On_Target then
1910             WBI ("      return Integer");
1911          end if;
1912
1913          WBI ("   is");
1914
1915       else
1916          if Exit_Status_Supported_On_Target then
1917             Set_String (" return Integer is");
1918          else
1919             Set_String (" is");
1920          end if;
1921
1922          Write_Statement_Buffer;
1923       end if;
1924
1925       if Opt.Default_Exit_Status /= 0
1926         and then Bind_Main_Program
1927         and then not Configurable_Run_Time_Mode
1928       then
1929          WBI ("      procedure Set_Exit_Status (Status : Integer);");
1930          WBI ("      pragma Import (C, Set_Exit_Status, " &
1931                      """__gnat_set_exit_status"");");
1932          WBI ("");
1933       end if;
1934
1935       --  Initialize and Finalize
1936
1937       if not Cumulative_Restrictions.Set (No_Finalization) then
1938          WBI ("      procedure Initialize (Addr : System.Address);");
1939          WBI ("      pragma Import (C, Initialize, ""__gnat_initialize"");");
1940          WBI ("");
1941          WBI ("      procedure Finalize;");
1942          WBI ("      pragma Import (C, Finalize, ""__gnat_finalize"");");
1943       end if;
1944
1945       --  If we want to analyze the stack, we have to import corresponding
1946       --  symbols
1947
1948       if Dynamic_Stack_Measurement then
1949          WBI ("");
1950          WBI ("      procedure Output_Results;");
1951          WBI ("      pragma Import (C, Output_Results, " &
1952               """__gnat_stack_usage_output_results"");");
1953
1954          WBI ("");
1955          WBI ("      " &
1956               "procedure Initialize_Stack_Analysis (Buffer_Size : Natural);");
1957          WBI ("      pragma Import (C, Initialize_Stack_Analysis, " &
1958               """__gnat_stack_usage_initialize"");");
1959       end if;
1960
1961       --  Deal with declarations for main program case
1962
1963       if not No_Main_Subprogram then
1964
1965          --  To call the main program, we declare it using a pragma Import
1966          --  Ada with the right link name.
1967
1968          --  It might seem more obvious to "with" the main program, and call
1969          --  it in the normal Ada manner. We do not do this for three reasons:
1970
1971          --    1. It is more efficient not to recompile the main program
1972          --    2. We are not entitled to assume the source is accessible
1973          --    3. We don't know what options to use to compile it
1974
1975          --  It is really reason 3 that is most critical (indeed we used
1976          --  to generate the "with", but several regression tests failed).
1977
1978          WBI ("");
1979
1980          if ALIs.Table (ALIs.First).Main_Program = Func then
1981             WBI ("      Result : Integer;");
1982             WBI ("");
1983             WBI ("      function Ada_Main_Program return Integer;");
1984
1985          else
1986             WBI ("      procedure Ada_Main_Program;");
1987          end if;
1988
1989          Set_String ("      pragma Import (Ada, Ada_Main_Program, """);
1990          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1991          Set_Main_Program_Name;
1992          Set_String (""");");
1993
1994          Write_Statement_Buffer;
1995          WBI ("");
1996
1997          if Bind_Main_Program
1998            and then not Suppress_Standard_Library_On_Target
1999          then
2000             WBI ("      SEH : aliased array (1 .. 2) of Integer;");
2001             WBI ("");
2002          end if;
2003       end if;
2004
2005       --  Generate a reference to Ada_Main_Program_Name. This symbol is
2006       --  not referenced elsewhere in the generated program, but is needed
2007       --  by the debugger (that's why it is generated in the first place).
2008       --  The reference stops Ada_Main_Program_Name from being optimized
2009       --  away by smart linkers, such as the AiX linker.
2010
2011       --  Because this variable is unused, we make this variable "aliased"
2012       --  with a pragma Volatile in order to tell the compiler to preserve
2013       --  this variable at any level of optimization.
2014
2015       if Bind_Main_Program then
2016          WBI
2017            ("      Ensure_Reference : aliased System.Address := " &
2018             "Ada_Main_Program_Name'Address;");
2019          WBI ("      pragma Volatile (Ensure_Reference);");
2020          WBI ("");
2021       end if;
2022
2023       WBI ("   begin");
2024
2025       --  Acquire command line arguments if present on target
2026
2027       if Command_Line_Args_On_Target then
2028          WBI ("      gnat_argc := argc;");
2029          WBI ("      gnat_argv := argv;");
2030          WBI ("      gnat_envp := envp;");
2031          WBI ("");
2032
2033       --  If configurable run time and no command line args, then nothing
2034       --  needs to be done since the gnat_argc/argv/envp variables are
2035       --  suppressed in this case.
2036
2037       elsif Configurable_Run_Time_On_Target then
2038          null;
2039
2040       --  Otherwise set dummy values (to be filled in by some other unit?)
2041
2042       else
2043          WBI ("      gnat_argc := 0;");
2044          WBI ("      gnat_argv := System.Null_Address;");
2045          WBI ("      gnat_envp := System.Null_Address;");
2046       end if;
2047
2048       if Opt.Default_Exit_Status /= 0
2049         and then Bind_Main_Program
2050         and then not Configurable_Run_Time_Mode
2051       then
2052          Set_String ("      Set_Exit_Status (");
2053          Set_Int (Opt.Default_Exit_Status);
2054          Set_String (");");
2055          Write_Statement_Buffer;
2056       end if;
2057
2058       if Dynamic_Stack_Measurement then
2059          Set_String ("      Initialize_Stack_Analysis (");
2060          Set_Int (Dynamic_Stack_Measurement_Array_Size);
2061          Set_String (");");
2062          Write_Statement_Buffer;
2063       end if;
2064
2065       if not Cumulative_Restrictions.Set (No_Finalization) then
2066          if not No_Main_Subprogram
2067            and then Bind_Main_Program
2068            and then not Suppress_Standard_Library_On_Target
2069          then
2070             WBI ("      Initialize (SEH'Address);");
2071          else
2072             WBI ("      Initialize (System.Null_Address);");
2073          end if;
2074       end if;
2075
2076       WBI ("      " & Ada_Init_Name.all & ";");
2077
2078       if not No_Main_Subprogram then
2079          WBI ("      Break_Start;");
2080
2081          if ALIs.Table (ALIs.First).Main_Program = Proc then
2082             WBI ("      Ada_Main_Program;");
2083          else
2084             WBI ("      Result := Ada_Main_Program;");
2085          end if;
2086       end if;
2087
2088       --  Adafinal call is skipped if no finalization
2089
2090       if not Cumulative_Restrictions.Set (No_Finalization) then
2091          WBI ("      adafinal;");
2092       end if;
2093
2094       --  Prints the result of static stack analysis
2095
2096       if Dynamic_Stack_Measurement then
2097          WBI ("      Output_Results;");
2098       end if;
2099
2100       --  Finalize is only called if we have a run time
2101
2102       if not Cumulative_Restrictions.Set (No_Finalization) then
2103          WBI ("      Finalize;");
2104       end if;
2105
2106       --  Return result
2107
2108       if Exit_Status_Supported_On_Target then
2109          if No_Main_Subprogram
2110            or else ALIs.Table (ALIs.First).Main_Program = Proc
2111          then
2112             WBI ("      return (gnat_exit_status);");
2113          else
2114             WBI ("      return (Result);");
2115          end if;
2116       end if;
2117
2118       WBI ("   end;");
2119       WBI ("");
2120    end Gen_Main_Ada;
2121
2122    ----------------
2123    -- Gen_Main_C --
2124    ----------------
2125
2126    procedure Gen_Main_C is
2127       Needs_Library_Finalization : constant Boolean :=
2128                                      not Configurable_Run_Time_On_Target
2129                                        and then Has_Finalizer;
2130       --  For restricted run-time libraries (ZFP and Ravenscar) tasks are
2131       --  non-terminating, so we do not want library-level finalization.
2132
2133    begin
2134       if Exit_Status_Supported_On_Target then
2135          WBI ("#include <stdlib.h>");
2136          Set_String ("int ");
2137       else
2138          Set_String ("void ");
2139       end if;
2140
2141       Set_String (Get_Main_Name);
2142
2143       --  Generate command line args in prototype if present on target
2144
2145       if Command_Line_Args_On_Target then
2146          Write_Statement_Buffer (" (int argc, char **argv, char **envp)");
2147
2148       --  Case of no command line arguments on target
2149
2150       else
2151          Write_Statement_Buffer (" (void)");
2152       end if;
2153
2154       WBI ("{");
2155
2156       --  Generate a reference to __gnat_ada_main_program_name. This symbol
2157       --  is  not referenced elsewhere in the generated program, but is
2158       --  needed by the debugger (that's why it is generated in the first
2159       --  place). The reference stops Ada_Main_Program_Name from being
2160       --  optimized away by smart linkers, such as the AiX linker.
2161
2162       --  Because this variable is unused, we declare this variable as
2163       --  volatile in order to tell the compiler to preserve it at any
2164       --  level of optimization.
2165
2166       if Bind_Main_Program then
2167          WBI ("   char * volatile ensure_reference " &
2168               "__attribute__ ((__unused__)) = " &
2169               "__gnat_ada_main_program_name;");
2170          WBI ("");
2171
2172          if not Suppress_Standard_Library_On_Target
2173            and then not No_Main_Subprogram
2174          then
2175             WBI ("   int SEH [2];");
2176             WBI ("");
2177          end if;
2178       end if;
2179
2180       --  If main program is a function, generate result variable
2181
2182       if ALIs.Table (ALIs.First).Main_Program = Func then
2183          WBI ("   int result;");
2184       end if;
2185
2186       --  Set command line argument values from parameters if command line
2187       --  arguments are present on target
2188
2189       if Command_Line_Args_On_Target then
2190          WBI ("   gnat_argc = argc;");
2191          WBI ("   gnat_argv = argv;");
2192          WBI ("   gnat_envp = envp;");
2193          WBI (" ");
2194
2195       --  If configurable run-time, then nothing to do, since in this case
2196       --  the gnat_argc/argv/envp variables are entirely suppressed.
2197
2198       elsif Configurable_Run_Time_On_Target then
2199          null;
2200
2201       --  if no command line arguments on target, set dummy values
2202
2203       else
2204          WBI ("   gnat_argc = 0;");
2205          WBI ("   gnat_argv = 0;");
2206          WBI ("   gnat_envp = 0;");
2207       end if;
2208
2209       if Opt.Default_Exit_Status /= 0
2210         and then Bind_Main_Program
2211         and then not Configurable_Run_Time_Mode
2212       then
2213          Set_String ("   __gnat_set_exit_status (");
2214          Set_Int (Opt.Default_Exit_Status);
2215          Set_String (");");
2216          Write_Statement_Buffer;
2217       end if;
2218
2219       --  Initializes dynamic stack measurement if needed
2220
2221       if Dynamic_Stack_Measurement then
2222          Set_String ("   __gnat_stack_usage_initialize (");
2223          Set_Int (Dynamic_Stack_Measurement_Array_Size);
2224          Set_String (");");
2225          Write_Statement_Buffer;
2226       end if;
2227
2228       --  The __gnat_initialize routine is used only if we have a run-time
2229
2230       if not Suppress_Standard_Library_On_Target then
2231          if not No_Main_Subprogram and then Bind_Main_Program then
2232             WBI ("   __gnat_initialize ((void *)SEH);");
2233          else
2234             WBI ("   __gnat_initialize ((void *)0);");
2235          end if;
2236       end if;
2237
2238       WBI ("   " & Ada_Init_Name.all & " ();");
2239
2240       if not No_Main_Subprogram then
2241          WBI ("   __gnat_break_start ();");
2242          WBI (" ");
2243
2244          --  Output main program name
2245
2246          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2247
2248          --  Main program is procedure case
2249
2250          if ALIs.Table (ALIs.First).Main_Program = Proc then
2251             Set_String ("   ");
2252             Set_Main_Program_Name;
2253             Set_String (" ();");
2254             Write_Statement_Buffer;
2255
2256          --  Main program is function case
2257
2258          else -- ALIs.Table (ALIs_First).Main_Program = Func
2259             Set_String ("   result = ");
2260             Set_Main_Program_Name;
2261             Set_String (" ();");
2262             Write_Statement_Buffer;
2263          end if;
2264
2265       end if;
2266
2267       --  Call adafinal if finalization active
2268
2269       if not Cumulative_Restrictions.Set (No_Finalization)
2270         and then Needs_Library_Finalization
2271       then
2272          Gen_Finalize_Library_C;
2273       end if;
2274
2275       --  Outputs the dynamic stack measurement if needed
2276
2277       if Dynamic_Stack_Measurement then
2278          WBI ("   __gnat_stack_usage_output_results ();");
2279       end if;
2280
2281       --  The finalize routine is used only if we have a run-time
2282
2283       if not Suppress_Standard_Library_On_Target then
2284          WBI ("   __gnat_finalize ();");
2285       end if;
2286
2287       --  Case of main program is a function, so the value it returns
2288       --  is the exit status in this case.
2289
2290       if ALIs.Table (ALIs.First).Main_Program = Func then
2291          if Exit_Status_Supported_On_Target then
2292
2293             --  VMS must use Posix exit routine in order to get the effect
2294             --  of a Unix compatible setting of the program exit status.
2295             --  For all other systems, we use the standard exit routine.
2296
2297             if OpenVMS_On_Target then
2298                WBI ("   decc$__posix_exit (result);");
2299             else
2300                WBI ("   exit (result);");
2301             end if;
2302          end if;
2303
2304       --  Case of main program is a procedure, in which case the exit
2305       --  status is whatever was set by a Set_Exit call most recently
2306
2307       else
2308          if Exit_Status_Supported_On_Target then
2309
2310             --  VMS must use Posix exit routine in order to get the effect
2311             --  of a Unix compatible setting of the program exit status.
2312             --  For all other systems, we use the standard exit routine.
2313
2314             if OpenVMS_On_Target then
2315                WBI ("   decc$__posix_exit (gnat_exit_status);");
2316             else
2317                WBI ("   exit (gnat_exit_status);");
2318             end if;
2319          end if;
2320       end if;
2321
2322       WBI ("}");
2323       WBI ("");
2324    end Gen_Main_C;
2325
2326    ------------------------------
2327    -- Gen_Object_Files_Options --
2328    ------------------------------
2329
2330    procedure Gen_Object_Files_Options is
2331       Lgnat : Natural;
2332       --  This keeps track of the position in the sorted set of entries
2333       --  in the Linker_Options table of where the first entry from an
2334       --  internal file appears.
2335
2336       Linker_Option_List_Started : Boolean := False;
2337       --  Set to True when "LINKER OPTION LIST" is displayed
2338
2339       procedure Write_Linker_Option;
2340       --  Write binder info linker option
2341
2342       -------------------------
2343       -- Write_Linker_Option --
2344       -------------------------
2345
2346       procedure Write_Linker_Option is
2347          Start : Natural;
2348          Stop  : Natural;
2349
2350       begin
2351          --  Loop through string, breaking at null's
2352
2353          Start := 1;
2354          while Start < Name_Len loop
2355
2356             --  Find null ending this section
2357
2358             Stop := Start + 1;
2359             while Name_Buffer (Stop) /= ASCII.NUL
2360               and then Stop <= Name_Len loop
2361                Stop := Stop + 1;
2362             end loop;
2363
2364             --  Process section if non-null
2365
2366             if Stop > Start then
2367                if Output_Linker_Option_List then
2368                   if not Zero_Formatting then
2369                      if not Linker_Option_List_Started then
2370                         Linker_Option_List_Started := True;
2371                         Write_Eol;
2372                         Write_Str ("     LINKER OPTION LIST");
2373                         Write_Eol;
2374                         Write_Eol;
2375                      end if;
2376
2377                      Write_Str ("   ");
2378                   end if;
2379
2380                   Write_Str (Name_Buffer (Start .. Stop - 1));
2381                   Write_Eol;
2382                end if;
2383                Write_Info_Ada_C
2384                  ("   --   ", "", Name_Buffer (Start .. Stop - 1));
2385             end if;
2386
2387             Start := Stop + 1;
2388          end loop;
2389       end Write_Linker_Option;
2390
2391    --  Start of processing for Gen_Object_Files_Options
2392
2393    begin
2394       Write_Info_Ada_C ("-- ", "/* ", " BEGIN Object file/option list");
2395
2396       if Object_List_Filename /= null then
2397          Set_List_File (Object_List_Filename.all);
2398       end if;
2399
2400       for E in Elab_Order.First .. Elab_Order.Last loop
2401
2402          --  If not spec that has an associated body, then generate a comment
2403          --  giving the name of the corresponding object file.
2404
2405          if (not Units.Table (Elab_Order.Table (E)).SAL_Interface)
2406            and then Units.Table (Elab_Order.Table (E)).Utype /= Is_Spec
2407          then
2408             Get_Name_String
2409               (ALIs.Table
2410                 (Units.Table (Elab_Order.Table (E)).My_ALI).Ofile_Full_Name);
2411
2412             --  If the presence of an object file is necessary or if it exists,
2413             --  then use it.
2414
2415             if not Hostparm.Exclude_Missing_Objects
2416               or else
2417                 System.OS_Lib.Is_Regular_File (Name_Buffer (1 .. Name_Len))
2418             then
2419                Write_Info_Ada_C ("   --   ", "", Name_Buffer (1 .. Name_Len));
2420
2421                if Output_Object_List then
2422                   Write_Str (Name_Buffer (1 .. Name_Len));
2423                   Write_Eol;
2424                end if;
2425
2426                --  Don't link with the shared library on VMS if an internal
2427                --  filename object is seen. Multiply defined symbols will
2428                --  result.
2429
2430                if OpenVMS_On_Target
2431                  and then Is_Internal_File_Name
2432                   (ALIs.Table
2433                    (Units.Table (Elab_Order.Table (E)).My_ALI).Sfile)
2434                then
2435                   --  Special case for g-trasym.obj (not included in libgnat)
2436
2437                   Get_Name_String (ALIs.Table
2438                             (Units.Table (Elab_Order.Table (E)).My_ALI).Sfile);
2439
2440                   if Name_Buffer (1 .. 8) /= "g-trasym" then
2441                      Opt.Shared_Libgnat := False;
2442                   end if;
2443                end if;
2444             end if;
2445          end if;
2446       end loop;
2447
2448       if Object_List_Filename /= null then
2449          Close_List_File;
2450       end if;
2451
2452       --  Add a "-Ldir" for each directory in the object path
2453       if VM_Target /= CLI_Target then
2454          for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
2455             declare
2456                Dir : constant String_Ptr := Dir_In_Obj_Search_Path (J);
2457             begin
2458                Name_Len := 0;
2459                Add_Str_To_Name_Buffer ("-L");
2460                Add_Str_To_Name_Buffer (Dir.all);
2461                Write_Linker_Option;
2462             end;
2463          end loop;
2464       end if;
2465
2466       --  Sort linker options
2467
2468       --  This sort accomplishes two important purposes:
2469
2470       --    a) All application files are sorted to the front, and all GNAT
2471       --       internal files are sorted to the end. This results in a well
2472       --       defined dividing line between the two sets of files, for the
2473       --       purpose of inserting certain standard library references into
2474       --       the linker arguments list.
2475
2476       --    b) Given two different units, we sort the linker options so that
2477       --       those from a unit earlier in the elaboration order comes later
2478       --       in the list. This is a heuristic designed to create a more
2479       --       friendly order of linker options when the operations appear in
2480       --       separate units. The idea is that if unit A must be elaborated
2481       --       before unit B, then it is more likely that B references
2482       --       libraries included by A, than vice versa, so we want libraries
2483       --       included by A to come after libraries included by B.
2484
2485       --  These two criteria are implemented by function Lt_Linker_Option. Note
2486       --  that a special case of b) is that specs are elaborated before bodies,
2487       --  so linker options from specs come after linker options for bodies,
2488       --  and again, the assumption is that libraries used by the body are more
2489       --  likely to reference libraries used by the spec, than vice versa.
2490
2491       Sort
2492         (Linker_Options.Last,
2493          Move_Linker_Option'Access,
2494          Lt_Linker_Option'Access);
2495
2496       --  Write user linker options, i.e. the set of linker options that come
2497       --  from all files other than GNAT internal files, Lgnat is left set to
2498       --  point to the first entry from a GNAT internal file, or past the end
2499       --  of the entries if there are no internal files.
2500
2501       Lgnat := Linker_Options.Last + 1;
2502
2503       for J in 1 .. Linker_Options.Last loop
2504          if not Linker_Options.Table (J).Internal_File then
2505             Get_Name_String (Linker_Options.Table (J).Name);
2506             Write_Linker_Option;
2507          else
2508             Lgnat := J;
2509             exit;
2510          end if;
2511       end loop;
2512
2513       --  Now we insert standard linker options that must appear after the
2514       --  entries from user files, and before the entries from GNAT run-time
2515       --  files. The reason for this decision is that libraries referenced
2516       --  by internal routines may reference these standard library entries.
2517
2518       --  Note that we do not insert anything when pragma No_Run_Time has been
2519       --  specified or when the standard libraries are not to be used,
2520       --  otherwise on some platforms, such as VMS, we may get duplicate
2521       --  symbols when linking.
2522
2523       if not (Opt.No_Run_Time_Mode or else Opt.No_Stdlib) then
2524          Name_Len := 0;
2525
2526          if Opt.Shared_Libgnat then
2527             Add_Str_To_Name_Buffer ("-shared");
2528          else
2529             Add_Str_To_Name_Buffer ("-static");
2530          end if;
2531
2532          --  Write directly to avoid -K output (why???)
2533
2534          Write_Info_Ada_C ("   --   ", "", Name_Buffer (1 .. Name_Len));
2535
2536          if With_DECGNAT then
2537             Name_Len := 0;
2538
2539             if Opt.Shared_Libgnat then
2540                Add_Str_To_Name_Buffer (Shared_Lib ("decgnat"));
2541             else
2542                Add_Str_To_Name_Buffer ("-ldecgnat");
2543             end if;
2544
2545             Write_Linker_Option;
2546          end if;
2547
2548          if With_GNARL then
2549             Name_Len := 0;
2550
2551             if Opt.Shared_Libgnat then
2552                Add_Str_To_Name_Buffer (Shared_Lib ("gnarl"));
2553             else
2554                Add_Str_To_Name_Buffer ("-lgnarl");
2555             end if;
2556
2557             Write_Linker_Option;
2558          end if;
2559
2560          Name_Len := 0;
2561
2562          if Opt.Shared_Libgnat then
2563             Add_Str_To_Name_Buffer (Shared_Lib ("gnat"));
2564          else
2565             Add_Str_To_Name_Buffer ("-lgnat");
2566          end if;
2567
2568          Write_Linker_Option;
2569       end if;
2570
2571       --  Write linker options from all internal files
2572
2573       for J in Lgnat .. Linker_Options.Last loop
2574          Get_Name_String (Linker_Options.Table (J).Name);
2575          Write_Linker_Option;
2576       end loop;
2577
2578       if Output_Linker_Option_List and then not Zero_Formatting then
2579          Write_Eol;
2580       end if;
2581
2582       if Ada_Bind_File then
2583          WBI ("--  END Object file/option list   ");
2584       else
2585          WBI ("    END Object file/option list */");
2586       end if;
2587    end Gen_Object_Files_Options;
2588
2589    ---------------------
2590    -- Gen_Output_File --
2591    ---------------------
2592
2593    procedure Gen_Output_File (Filename : String) is
2594    begin
2595       --  Acquire settings for Interrupt_State pragmas
2596
2597       Set_IS_Pragma_Table;
2598
2599       --  Acquire settings for Priority_Specific_Dispatching pragma
2600
2601       Set_PSD_Pragma_Table;
2602
2603       --  Override Ada_Bind_File and Bind_Main_Program for VMs since JGNAT only
2604       --  supports Ada code, and the main program is already generated by the
2605       --  compiler.
2606
2607       if VM_Target /= No_VM then
2608          Ada_Bind_File := True;
2609
2610          if VM_Target = JVM_Target then
2611             Bind_Main_Program := False;
2612          end if;
2613       end if;
2614
2615       --  Override time slice value if -T switch is set
2616
2617       if Time_Slice_Set then
2618          ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value;
2619       end if;
2620
2621       --  Count number of elaboration calls
2622
2623       for E in Elab_Order.First .. Elab_Order.Last loop
2624          if Units.Table (Elab_Order.Table (E)).No_Elab then
2625             null;
2626          else
2627             Num_Elab_Calls := Num_Elab_Calls + 1;
2628          end if;
2629       end loop;
2630
2631       --  Generate output file in appropriate language
2632
2633       Check_System_Restrictions_Used;
2634
2635       if Ada_Bind_File then
2636          Gen_Output_File_Ada (Filename);
2637       else
2638          Gen_Output_File_C (Filename);
2639       end if;
2640    end Gen_Output_File;
2641
2642    -------------------------
2643    -- Gen_Output_File_Ada --
2644    -------------------------
2645
2646    procedure Gen_Output_File_Ada (Filename : String) is
2647
2648       Ada_Main : constant String := Get_Ada_Main_Name;
2649       --  Name to be used for generated Ada main program. See the body of
2650       --  function Get_Ada_Main_Name for details on the form of the name.
2651
2652       Needs_Library_Finalization : constant Boolean :=
2653                                      not Configurable_Run_Time_On_Target
2654                                        and then Has_Finalizer;
2655       --  For restricted run-time libraries (ZFP and Ravenscar) tasks are
2656       --  non-terminating, so we do not want finalization.
2657
2658       Bfiles : Name_Id;
2659       --  Name of generated bind file (spec)
2660
2661       Bfileb : Name_Id;
2662       --  Name of generated bind file (body)
2663
2664    begin
2665       --  Create spec first
2666
2667       Create_Binder_Output (Filename, 's', Bfiles);
2668
2669       --  We always compile the binder file in Ada 95 mode so that we properly
2670       --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2671       --  of the Ada 2005 constructs are needed by the binder file.
2672
2673       WBI ("pragma Ada_95;");
2674
2675       --  If we are operating in Restrictions (No_Exception_Handlers) mode,
2676       --  then we need to make sure that the binder program is compiled with
2677       --  the same restriction, so that no exception tables are generated.
2678
2679       if Cumulative_Restrictions.Set (No_Exception_Handlers) then
2680          WBI ("pragma Restrictions (No_Exception_Handlers);");
2681       end if;
2682
2683       --  Same processing for Restrictions (No_Exception_Propagation)
2684
2685       if Cumulative_Restrictions.Set (No_Exception_Propagation) then
2686          WBI ("pragma Restrictions (No_Exception_Propagation);");
2687       end if;
2688
2689       --  Same processing for pragma No_Run_Time
2690
2691       if No_Run_Time_Mode then
2692          WBI ("pragma No_Run_Time;");
2693       end if;
2694
2695       --  Generate with of System so we can reference System.Address
2696
2697       WBI ("with System;");
2698
2699       --  Generate with of System.Initialize_Scalars if active
2700
2701       if Initialize_Scalars_Used then
2702          WBI ("with System.Scalar_Values;");
2703       end if;
2704
2705       --  Generate with of System.Secondary_Stack if active
2706
2707       if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
2708          WBI ("with System.Secondary_Stack;");
2709       end if;
2710
2711       Resolve_Binder_Options;
2712
2713       --  Usually, adafinal is called using a pragma Import C. Since Import C
2714       --  doesn't have the same semantics for JGNAT, we use standard Ada.
2715
2716       if VM_Target /= No_VM
2717         and then not Suppress_Standard_Library_On_Target
2718       then
2719          WBI ("with System.Soft_Links;");
2720          WBI ("with System.Standard_Library;");
2721       end if;
2722
2723       WBI ("package " & Ada_Main & " is");
2724       WBI ("   pragma Warnings (Off);");
2725
2726       --  Main program case
2727
2728       if Bind_Main_Program then
2729          if VM_Target = No_VM then
2730
2731             --  Generate argc/argv stuff unless suppressed
2732
2733             if Command_Line_Args_On_Target
2734               or not Configurable_Run_Time_On_Target
2735             then
2736                WBI ("");
2737                WBI ("   gnat_argc : Integer;");
2738                WBI ("   gnat_argv : System.Address;");
2739                WBI ("   gnat_envp : System.Address;");
2740
2741                --  If the standard library is not suppressed, these variables
2742                --  are in the run-time data area for easy run time access.
2743
2744                if not Suppress_Standard_Library_On_Target then
2745                   WBI ("");
2746                   WBI ("   pragma Import (C, gnat_argc);");
2747                   WBI ("   pragma Import (C, gnat_argv);");
2748                   WBI ("   pragma Import (C, gnat_envp);");
2749                end if;
2750             end if;
2751
2752             --  Define exit status. Again in normal mode, this is in the
2753             --  run-time library, and is initialized there, but in the
2754             --  configurable runtime case, the variable is declared and
2755             --  initialized in this file.
2756
2757             WBI ("");
2758
2759             if Configurable_Run_Time_Mode then
2760                if Exit_Status_Supported_On_Target then
2761                   WBI ("   gnat_exit_status : Integer := 0;");
2762                end if;
2763
2764             else
2765                WBI ("   gnat_exit_status : Integer;");
2766                WBI ("   pragma Import (C, gnat_exit_status);");
2767             end if;
2768          end if;
2769
2770          --  Generate the GNAT_Version and Ada_Main_Program_Name info only for
2771          --  the main program. Otherwise, it can lead under some circumstances
2772          --  to a symbol duplication during the link (for instance when a C
2773          --  program uses two Ada libraries). Also zero terminate the string
2774          --  so that its end can be found reliably at run time.
2775
2776          WBI ("");
2777          WBI ("   GNAT_Version : constant String :=");
2778          WBI ("                    """ & Ver_Prefix &
2779                                    Gnat_Version_String &
2780                                    """ & ASCII.NUL;");
2781          WBI ("   pragma Export (C, GNAT_Version, ""__gnat_version"");");
2782
2783          WBI ("");
2784          Set_String ("   Ada_Main_Program_Name : constant String := """);
2785          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2786
2787          if VM_Target = No_VM then
2788             Set_Main_Program_Name;
2789             Set_String (""" & ASCII.NUL;");
2790          else
2791             Set_String (Name_Buffer (1 .. Name_Len - 2) & """;");
2792          end if;
2793
2794          Write_Statement_Buffer;
2795
2796          WBI
2797            ("   pragma Export (C, Ada_Main_Program_Name, " &
2798             """__gnat_ada_main_program_name"");");
2799       end if;
2800
2801       if not Cumulative_Restrictions.Set (No_Finalization) then
2802          WBI ("");
2803          WBI ("   procedure " & Ada_Final_Name.all & ";");
2804          WBI ("   pragma Export (C, " & Ada_Final_Name.all & ", """ &
2805               Ada_Final_Name.all & """);");
2806       end if;
2807
2808       WBI ("");
2809       WBI ("   procedure " & Ada_Init_Name.all & ";");
2810       WBI ("   pragma Export (C, " & Ada_Init_Name.all & ", """ &
2811            Ada_Init_Name.all & """);");
2812
2813       --  If -a has been specified use pragma Linker_Constructor for the init
2814       --  procedure. No need to use a similar pragma for the final procedure as
2815       --  global finalization will occur when the executable finishes execution
2816       --  and for plugins (shared stand-alone libraries that can be
2817       --  "unloaded"), finalization should not occur automatically, otherwise
2818       --  the main executable may not continue to work properly.
2819
2820       if Use_Pragma_Linker_Constructor then
2821          WBI ("   pragma Linker_Constructor (" & Ada_Init_Name.all & ");");
2822       end if;
2823
2824       if Bind_Main_Program and then VM_Target = No_VM then
2825
2826          --  If we have the standard library, then Break_Start is defined
2827          --  there, but when the standard library is suppressed, Break_Start
2828          --  is defined here.
2829
2830          WBI ("");
2831          WBI ("   procedure Break_Start;");
2832
2833          if Suppress_Standard_Library_On_Target then
2834             WBI ("   pragma Export (C, Break_Start, ""__gnat_break_start"");");
2835          else
2836             WBI ("   pragma Import (C, Break_Start, ""__gnat_break_start"");");
2837          end if;
2838
2839          WBI ("");
2840
2841          if Exit_Status_Supported_On_Target then
2842             Set_String ("   function ");
2843          else
2844             Set_String ("   procedure ");
2845          end if;
2846
2847          Set_String (Get_Main_Name);
2848
2849          --  Generate argument list if present
2850
2851          if Command_Line_Args_On_Target then
2852             Write_Statement_Buffer;
2853             WBI ("     (argc : Integer;");
2854             WBI ("      argv : System.Address;");
2855             Set_String
2856                 ("      envp : System.Address)");
2857
2858             if Exit_Status_Supported_On_Target then
2859                Write_Statement_Buffer;
2860                WBI ("      return Integer;");
2861             else
2862                Write_Statement_Buffer (";");
2863             end if;
2864
2865          else
2866             if Exit_Status_Supported_On_Target then
2867                Write_Statement_Buffer (" return Integer;");
2868             else
2869                Write_Statement_Buffer (";");
2870             end if;
2871          end if;
2872
2873          WBI ("   pragma Export (C, " & Get_Main_Name & ", """ &
2874            Get_Main_Name & """);");
2875       end if;
2876
2877       Gen_Versions_Ada;
2878       Gen_Elab_Order_Ada;
2879
2880       --  Spec is complete
2881
2882       WBI ("");
2883       WBI ("end " & Ada_Main & ";");
2884       Close_Binder_Output;
2885
2886       --  Prepare to write body
2887
2888       Create_Binder_Output (Filename, 'b', Bfileb);
2889
2890       --  We always compile the binder file in Ada 95 mode so that we properly
2891       --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2892       --  of the Ada 2005 constructs are needed by the binder file.
2893
2894       WBI ("pragma Ada_95;");
2895
2896       --  Output Source_File_Name pragmas which look like
2897
2898       --    pragma Source_File_Name (Ada_Main, Spec_File_Name => "sss");
2899       --    pragma Source_File_Name (Ada_Main, Body_File_Name => "bbb");
2900
2901       --  where sss/bbb are the spec/body file names respectively
2902
2903       Get_Name_String (Bfiles);
2904       Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2905
2906       WBI ("pragma Source_File_Name (" &
2907            Ada_Main &
2908            ", Spec_File_Name => """ &
2909            Name_Buffer (1 .. Name_Len + 3));
2910
2911       Get_Name_String (Bfileb);
2912       Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2913
2914       WBI ("pragma Source_File_Name (" &
2915            Ada_Main &
2916            ", Body_File_Name => """ &
2917            Name_Buffer (1 .. Name_Len + 3));
2918
2919       --  Generate with of System.Restrictions to initialize
2920       --  Run_Time_Restrictions.
2921
2922       if System_Restrictions_Used
2923         and not Suppress_Standard_Library_On_Target
2924       then
2925          WBI ("");
2926          WBI ("with System.Restrictions;");
2927       end if;
2928
2929       if Needs_Library_Finalization then
2930          WBI ("with Ada.Exceptions;");
2931       end if;
2932
2933       WBI ("");
2934       WBI ("package body " & Ada_Main & " is");
2935       WBI ("   pragma Warnings (Off);");
2936
2937       if not Suppress_Standard_Library_On_Target then
2938
2939          --  Generate Priority_Specific_Dispatching pragma string
2940
2941          Set_String
2942            ("   Local_Priority_Specific_Dispatching : constant String := """);
2943
2944          for J in 0 .. PSD_Pragma_Settings.Last loop
2945             Set_Char (PSD_Pragma_Settings.Table (J));
2946          end loop;
2947
2948          Set_String (""";");
2949          Write_Statement_Buffer;
2950
2951          --  Generate Interrupt_State pragma string
2952
2953          Set_String ("   Local_Interrupt_States : constant String := """);
2954
2955          for J in 0 .. IS_Pragma_Settings.Last loop
2956             Set_Char (IS_Pragma_Settings.Table (J));
2957          end loop;
2958
2959          Set_String (""";");
2960          Write_Statement_Buffer;
2961          WBI ("");
2962       end if;
2963
2964       --  Generate the adafinal routine unless there is no finalization to do
2965
2966       if not Cumulative_Restrictions.Set (No_Finalization) then
2967          Gen_Adafinal_Ada;
2968
2969          if Needs_Library_Finalization then
2970             Gen_Finalize_Library_Ada;
2971          end if;
2972       end if;
2973
2974       Gen_Adainit_Ada;
2975
2976       if Bind_Main_Program and then VM_Target = No_VM then
2977
2978          --  When suppressing the standard library then generate dummy body
2979          --  for Break_Start
2980
2981          if Suppress_Standard_Library_On_Target then
2982             WBI ("");
2983             WBI ("   procedure Break_Start is");
2984             WBI ("   begin");
2985             WBI ("      null;");
2986             WBI ("   end;");
2987          end if;
2988
2989          Gen_Main_Ada;
2990       end if;
2991
2992       --  Output object file list and the Ada body is complete
2993
2994       Gen_Object_Files_Options;
2995
2996       WBI ("");
2997       WBI ("end " & Ada_Main & ";");
2998
2999       Close_Binder_Output;
3000    end Gen_Output_File_Ada;
3001
3002    -----------------------
3003    -- Gen_Output_File_C --
3004    -----------------------
3005
3006    procedure Gen_Output_File_C (Filename : String) is
3007
3008       Needs_Library_Finalization : constant Boolean :=
3009                                      not Configurable_Run_Time_On_Target
3010                                        and then Has_Finalizer;
3011       --  ??? seems like we repeat this cantation often, should it be global?
3012
3013       Bfile : Name_Id;
3014       pragma Warnings (Off, Bfile);
3015       --  Name of generated bind file (not referenced)
3016
3017    begin
3018       Create_Binder_Output (Filename, 'c', Bfile);
3019
3020       Resolve_Binder_Options;
3021
3022       WBI ("extern void " & Ada_Final_Name.all & " (void);");
3023
3024       --  If -a has been specified use __attribute__((constructor)) for the
3025       --  init procedure. No need to use a similar featute for the final
3026       --  procedure as global finalization will occur when the executable
3027       --  finishes execution and for plugins (shared stand-alone libraries that
3028       --  can be "unloaded"), finalization should not occur automatically,
3029       --  otherwise the main executable may not continue to work properly.
3030
3031       if Use_Pragma_Linker_Constructor then
3032          WBI ("extern void " & Ada_Init_Name.all &
3033               " (void) __attribute__((constructor));");
3034       else
3035          WBI ("extern void " & Ada_Init_Name.all & " (void);");
3036       end if;
3037
3038       WBI ("extern void system__standard_library__adafinal (void);");
3039
3040       if not No_Main_Subprogram then
3041          Set_String ("extern ");
3042
3043          if Exit_Status_Supported_On_Target then
3044             Set_String ("int");
3045          else
3046             Set_String ("void");
3047          end if;
3048
3049          Set_String (" main ");
3050
3051          if Command_Line_Args_On_Target then
3052             Write_Statement_Buffer ("(int, char **, char **);");
3053          else
3054             Write_Statement_Buffer ("(void);");
3055          end if;
3056
3057          if OpenVMS_On_Target then
3058             WBI ("extern void decc$__posix_exit (int);");
3059          else
3060             WBI ("extern void exit (int);");
3061          end if;
3062
3063          WBI ("extern void __gnat_break_start (void);");
3064          Set_String ("extern ");
3065
3066          if ALIs.Table (ALIs.First).Main_Program = Proc then
3067             Set_String ("void ");
3068          else
3069             Set_String ("int ");
3070          end if;
3071
3072          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
3073          Set_Main_Program_Name;
3074          Set_String (" (void);");
3075          Write_Statement_Buffer;
3076       end if;
3077
3078       if not Suppress_Standard_Library_On_Target then
3079          WBI ("extern void __gnat_initialize (void *);");
3080          WBI ("extern void __gnat_finalize (void);");
3081          WBI ("extern void __gnat_install_handler (void);");
3082       end if;
3083
3084       if Dynamic_Stack_Measurement then
3085          WBI ("");
3086          WBI ("extern void __gnat_stack_usage_output_results (void);");
3087          WBI ("extern void __gnat_stack_usage_initialize (int size);");
3088       end if;
3089
3090       --  Initialize stack limit for the environment task if the stack check
3091       --  method is stack limit and stack check is enabled.
3092
3093       if Stack_Check_Limits_On_Target
3094         and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
3095       then
3096          WBI ("");
3097          WBI ("extern void __gnat_initialize_stack_limit (void);");
3098       end if;
3099
3100       WBI ("");
3101
3102       Gen_Elab_Defs_C;
3103
3104       if Needs_Library_Finalization then
3105          Gen_Finalize_Library_Defs_C;
3106       end if;
3107
3108       --  Imported variables used only when we have a runtime
3109
3110       if not Suppress_Standard_Library_On_Target then
3111
3112          --  Track elaboration/finalization phase
3113
3114          WBI ("extern int  __gnat_handler_installed;");
3115          WBI ("");
3116
3117          --  Track feature enable/disable on VMS
3118
3119          if OpenVMS_On_Target then
3120             WBI ("extern int  __gnat_features_set;");
3121             WBI ("");
3122          end if;
3123       end if;
3124
3125       --  Write argv/argc exit status stuff if main program case
3126
3127       if Bind_Main_Program then
3128
3129          --  First deal with argc/argv/envp. In the normal case they are in the
3130          --  run-time library.
3131
3132          if not Configurable_Run_Time_On_Target then
3133             WBI ("extern int gnat_argc;");
3134             WBI ("extern char **gnat_argv;");
3135             WBI ("extern char **gnat_envp;");
3136
3137          --  If configurable run time and no command line args, then the
3138          --  generation of these variables is entirely suppressed.
3139
3140          elsif not Command_Line_Args_On_Target then
3141             null;
3142
3143          --  Otherwise, in the configurable run-time case they are right in the
3144          --  binder file.
3145
3146          else
3147             WBI ("int gnat_argc;");
3148             WBI ("char **gnat_argv;");
3149             WBI ("char **gnat_envp;");
3150          end if;
3151
3152          --  Similarly deal with exit status
3153
3154          if not Configurable_Run_Time_On_Target then
3155             WBI ("extern int gnat_exit_status;");
3156
3157          --  If configurable run time and no exit status on target, then the
3158          --  generation of this variables is entirely suppressed.
3159
3160          elsif not Exit_Status_Supported_On_Target then
3161             null;
3162
3163          --  Otherwise, in the configurable run-time case this variable is
3164          --  right in the binder file, and initialized to zero there.
3165
3166          else
3167             WBI ("int gnat_exit_status = 0;");
3168          end if;
3169
3170          WBI ("");
3171       end if;
3172
3173       --  When suppressing the standard library, the __gnat_break_start routine
3174       --  (for the debugger to get initial control) is defined in this file.
3175
3176       if Suppress_Standard_Library_On_Target then
3177          WBI ("");
3178          WBI ("void __gnat_break_start (void) {}");
3179       end if;
3180
3181       --  Generate the __gnat_version and __gnat_ada_main_program_name info
3182       --  only for the main program. Otherwise, it can lead under some
3183       --  circumstances to a symbol duplication during the link (for instance
3184       --  when a C program uses 2 Ada libraries)
3185
3186       if Bind_Main_Program then
3187          WBI ("");
3188          WBI ("char __gnat_version[] = """ & Ver_Prefix &
3189                                    Gnat_Version_String & """;");
3190
3191          Set_String ("char __gnat_ada_main_program_name[] = """);
3192          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
3193          Set_Main_Program_Name;
3194          Set_String (""";");
3195          Write_Statement_Buffer;
3196       end if;
3197
3198       --  Generate the adafinal routine. In no runtime mode, this is not
3199       --  needed, since there is no finalization to do.
3200
3201       if not Cumulative_Restrictions.Set (No_Finalization) then
3202          Gen_Adafinal_C;
3203       end if;
3204
3205       Gen_Adainit_C;
3206
3207       --  Main is only present for Ada main case
3208
3209       if Bind_Main_Program then
3210          Gen_Main_C;
3211       end if;
3212
3213       --  Generate versions, elaboration order, list of object files
3214
3215       Gen_Versions_C;
3216       Gen_Elab_Order_C;
3217       Gen_Object_Files_Options;
3218
3219       --  C binder output is complete
3220
3221       Close_Binder_Output;
3222    end Gen_Output_File_C;
3223
3224    --------------------------
3225    -- Gen_Restrictions_Ada --
3226    --------------------------
3227
3228    procedure Gen_Restrictions_Ada is
3229       Count : Integer;
3230
3231    begin
3232       if Suppress_Standard_Library_On_Target
3233         or not System_Restrictions_Used
3234       then
3235          return;
3236       end if;
3237
3238       WBI ("      System.Restrictions.Run_Time_Restrictions :=");
3239       WBI ("        (Set =>");
3240       Set_String      ("          (");
3241
3242       Count := 0;
3243
3244       for J in Cumulative_Restrictions.Set'Range loop
3245          Set_Boolean (Cumulative_Restrictions.Set (J));
3246          Set_String (", ");
3247          Count := Count + 1;
3248
3249          if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
3250             Write_Statement_Buffer;
3251             Set_String ("           ");
3252             Count := 0;
3253          end if;
3254       end loop;
3255
3256       Set_String_Replace ("),");
3257       Write_Statement_Buffer;
3258       Set_String ("         Value => (");
3259
3260       for J in Cumulative_Restrictions.Value'Range loop
3261          Set_Int (Int (Cumulative_Restrictions.Value (J)));
3262          Set_String (", ");
3263       end loop;
3264
3265       Set_String_Replace ("),");
3266       Write_Statement_Buffer;
3267       WBI ("         Violated =>");
3268       Set_String ("          (");
3269       Count := 0;
3270
3271       for J in Cumulative_Restrictions.Violated'Range loop
3272          Set_Boolean (Cumulative_Restrictions.Violated (J));
3273          Set_String (", ");
3274          Count := Count + 1;
3275
3276          if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
3277             Write_Statement_Buffer;
3278             Set_String ("           ");
3279             Count := 0;
3280          end if;
3281       end loop;
3282
3283       Set_String_Replace ("),");
3284       Write_Statement_Buffer;
3285       Set_String ("         Count => (");
3286
3287       for J in Cumulative_Restrictions.Count'Range loop
3288          Set_Int (Int (Cumulative_Restrictions.Count (J)));
3289          Set_String (", ");
3290       end loop;
3291
3292       Set_String_Replace ("),");
3293       Write_Statement_Buffer;
3294       Set_String ("         Unknown => (");
3295
3296       for J in Cumulative_Restrictions.Unknown'Range loop
3297          Set_Boolean (Cumulative_Restrictions.Unknown (J));
3298          Set_String (", ");
3299       end loop;
3300
3301       Set_String_Replace ("))");
3302       Set_String (";");
3303       Write_Statement_Buffer;
3304    end Gen_Restrictions_Ada;
3305
3306    ------------------------
3307    -- Gen_Restrictions_C --
3308    ------------------------
3309
3310    procedure Gen_Restrictions_C is
3311    begin
3312       if Suppress_Standard_Library_On_Target
3313         or not System_Restrictions_Used
3314       then
3315          return;
3316       end if;
3317
3318       WBI ("   typedef struct {");
3319       Set_String ("     char set [");
3320       Set_Int (Cumulative_Restrictions.Set'Length);
3321       Set_String ("];");
3322       Write_Statement_Buffer;
3323
3324       Set_String ("     int value [");
3325       Set_Int (Cumulative_Restrictions.Value'Length);
3326       Set_String ("];");
3327       Write_Statement_Buffer;
3328
3329       Set_String ("     char violated [");
3330       Set_Int (Cumulative_Restrictions.Violated'Length);
3331       Set_String ("];");
3332       Write_Statement_Buffer;
3333
3334       Set_String ("     int count [");
3335       Set_Int (Cumulative_Restrictions.Count'Length);
3336       Set_String ("];");
3337       Write_Statement_Buffer;
3338
3339       Set_String ("     char unknown [");
3340       Set_Int (Cumulative_Restrictions.Unknown'Length);
3341       Set_String ("];");
3342       Write_Statement_Buffer;
3343       WBI ("   } restrictions;");
3344       WBI ("   extern restrictions " &
3345            "system__restrictions__run_time_restrictions;");
3346       WBI ("   restrictions r = {");
3347       Set_String ("     {");
3348
3349       for J in Cumulative_Restrictions.Set'Range loop
3350          Set_Int (Boolean'Pos (Cumulative_Restrictions.Set (J)));
3351          Set_String (", ");
3352       end loop;
3353
3354       Set_String_Replace ("},");
3355       Write_Statement_Buffer;
3356       Set_String ("     {");
3357
3358       for J in Cumulative_Restrictions.Value'Range loop
3359          Set_Int (Int (Cumulative_Restrictions.Value (J)));
3360          Set_String (", ");
3361       end loop;
3362
3363       Set_String_Replace ("},");
3364       Write_Statement_Buffer;
3365       Set_String ("     {");
3366
3367       for J in Cumulative_Restrictions.Violated'Range loop
3368          Set_Int (Boolean'Pos (Cumulative_Restrictions.Violated (J)));
3369          Set_String (", ");
3370       end loop;
3371
3372       Set_String_Replace ("},");
3373       Write_Statement_Buffer;
3374       Set_String ("     {");
3375
3376       for J in Cumulative_Restrictions.Count'Range loop
3377          Set_Int (Int (Cumulative_Restrictions.Count (J)));
3378          Set_String (", ");
3379       end loop;
3380
3381       Set_String_Replace ("},");
3382       Write_Statement_Buffer;
3383       Set_String ("     {");
3384
3385       for J in Cumulative_Restrictions.Unknown'Range loop
3386          Set_Int (Boolean'Pos (Cumulative_Restrictions.Unknown (J)));
3387          Set_String (", ");
3388       end loop;
3389
3390       Set_String_Replace ("}}");
3391       Set_String (";");
3392       Write_Statement_Buffer;
3393       WBI ("   system__restrictions__run_time_restrictions = r;");
3394    end Gen_Restrictions_C;
3395
3396    ----------------------
3397    -- Gen_Versions_Ada --
3398    ----------------------
3399
3400    --  This routine generates lines such as:
3401
3402    --    unnnnn : constant Integer := 16#hhhhhhhh#;
3403    --    pragma Export (C, unnnnn, unam);
3404
3405    --  for each unit, where unam is the unit name suffixed by either B or S for
3406    --  body or spec, with dots replaced by double underscores, and hhhhhhhh is
3407    --  the version number, and nnnnn is a 5-digits serial number.
3408
3409    procedure Gen_Versions_Ada is
3410       Ubuf : String (1 .. 6) := "u00000";
3411
3412       procedure Increment_Ubuf;
3413       --  Little procedure to increment the serial number
3414
3415       --------------------
3416       -- Increment_Ubuf --
3417       --------------------
3418
3419       procedure Increment_Ubuf is
3420       begin
3421          for J in reverse Ubuf'Range loop
3422             Ubuf (J) := Character'Succ (Ubuf (J));
3423             exit when Ubuf (J) <= '9';
3424             Ubuf (J) := '0';
3425          end loop;
3426       end Increment_Ubuf;
3427
3428    --  Start of processing for Gen_Versions_Ada
3429
3430    begin
3431       WBI ("");
3432
3433       WBI ("   type Version_32 is mod 2 ** 32;");
3434       for U in Units.First .. Units.Last loop
3435          if not Units.Table (U).SAL_Interface and then
3436            ((not Bind_For_Library) or else Units.Table (U).Directly_Scanned)
3437          then
3438             Increment_Ubuf;
3439             WBI ("   " & Ubuf & " : constant Version_32 := 16#" &
3440                  Units.Table (U).Version & "#;");
3441             Set_String ("   pragma Export (C, ");
3442             Set_String (Ubuf);
3443             Set_String (", """);
3444
3445             Get_Name_String (Units.Table (U).Uname);
3446
3447             for K in 1 .. Name_Len loop
3448                if Name_Buffer (K) = '.' then
3449                   Set_Char ('_');
3450                   Set_Char ('_');
3451
3452                elsif Name_Buffer (K) = '%' then
3453                   exit;
3454
3455                else
3456                   Set_Char (Name_Buffer (K));
3457                end if;
3458             end loop;
3459
3460             if Name_Buffer (Name_Len) = 's' then
3461                Set_Char ('S');
3462             else
3463                Set_Char ('B');
3464             end if;
3465
3466             Set_String (""");");
3467             Write_Statement_Buffer;
3468          end if;
3469       end loop;
3470    end Gen_Versions_Ada;
3471
3472    --------------------
3473    -- Gen_Versions_C --
3474    --------------------
3475
3476    --  This routine generates a line of the form:
3477
3478    --    unsigned unam = 0xhhhhhhhh;
3479
3480    --  for each unit, where unam is the unit name suffixed by either B or S for
3481    --  body or spec, with dots replaced by double underscores.
3482
3483    procedure Gen_Versions_C is
3484    begin
3485       for U in Units.First .. Units.Last loop
3486          if not Units.Table (U).SAL_Interface and then
3487            ((not Bind_For_Library) or else Units.Table (U).Directly_Scanned)
3488          then
3489             Set_String ("unsigned ");
3490
3491             Get_Name_String (Units.Table (U).Uname);
3492
3493             for K in 1 .. Name_Len loop
3494                if Name_Buffer (K) = '.' then
3495                   Set_String ("__");
3496
3497                elsif Name_Buffer (K) = '%' then
3498                   exit;
3499
3500                else
3501                   Set_Char (Name_Buffer (K));
3502                end if;
3503             end loop;
3504
3505             if Name_Buffer (Name_Len) = 's' then
3506                Set_Char ('S');
3507             else
3508                Set_Char ('B');
3509             end if;
3510
3511             Set_String (" = 0x");
3512             Set_String (Units.Table (U).Version);
3513             Set_Char   (';');
3514             Write_Statement_Buffer;
3515          end if;
3516       end loop;
3517    end Gen_Versions_C;
3518
3519    ------------------------
3520    -- Get_Main_Unit_Name --
3521    ------------------------
3522
3523    function Get_Main_Unit_Name (S : String) return String is
3524       Result : String := S;
3525
3526    begin
3527       for J in S'Range loop
3528          if Result (J) = '.' then
3529             Result (J) := '_';
3530          end if;
3531       end loop;
3532
3533       return Result;
3534    end Get_Main_Unit_Name;
3535
3536    -----------------------
3537    -- Get_Ada_Main_Name --
3538    -----------------------
3539
3540    function Get_Ada_Main_Name return String is
3541       Suffix : constant String := "_00";
3542       Name   : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
3543                  Opt.Ada_Main_Name.all & Suffix;
3544       Nlen   : Natural;
3545
3546    begin
3547       --  The main program generated by JGNAT expects a package called
3548       --  ada_<main procedure>.
3549
3550       if VM_Target /= No_VM then
3551          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
3552          return "ada_" & Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
3553       end if;
3554
3555       --  This loop tries the following possibilities in order
3556       --    <Ada_Main>
3557       --    <Ada_Main>_01
3558       --    <Ada_Main>_02
3559       --    ..
3560       --    <Ada_Main>_99
3561       --  where <Ada_Main> is equal to Opt.Ada_Main_Name. By default,
3562       --  it is set to 'ada_main'.
3563
3564       for J in 0 .. 99 loop
3565          if J = 0 then
3566             Nlen := Name'Length - Suffix'Length;
3567          else
3568             Nlen := Name'Length;
3569             Name (Name'Last) := Character'Val (J mod 10 + Character'Pos ('0'));
3570             Name (Name'Last - 1) :=
3571               Character'Val (J /   10 + Character'Pos ('0'));
3572          end if;
3573
3574          for K in ALIs.First .. ALIs.Last loop
3575             for L in ALIs.Table (K).First_Unit .. ALIs.Table (K).Last_Unit loop
3576
3577                --  Get unit name, removing %b or %e at end
3578
3579                Get_Name_String (Units.Table (L).Uname);
3580                Name_Len := Name_Len - 2;
3581
3582                if Name_Buffer (1 .. Name_Len) = Name (1 .. Nlen) then
3583                   goto Continue;
3584                end if;
3585             end loop;
3586          end loop;
3587
3588          return Name (1 .. Nlen);
3589
3590       <<Continue>>
3591          null;
3592       end loop;
3593
3594       --  If we fall through, just use a peculiar unlikely name
3595
3596       return ("Qwertyuiop");
3597    end Get_Ada_Main_Name;
3598
3599    -------------------
3600    -- Get_Main_Name --
3601    -------------------
3602
3603    function Get_Main_Name return String is
3604    begin
3605       --  Explicit name given with -M switch
3606
3607       if Bind_Alternate_Main_Name then
3608          return Alternate_Main_Name.all;
3609
3610       --  Case of main program name to be used directly
3611
3612       elsif Use_Ada_Main_Program_Name_On_Target then
3613
3614          --  Get main program name
3615
3616          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
3617
3618          --  If this is a child name, return only the name of the child, since
3619          --  we can't have dots in a nested program name. Note that we do not
3620          --  include the %b at the end of the unit name.
3621
3622          for J in reverse 1 .. Name_Len - 2 loop
3623             if J = 1 or else Name_Buffer (J - 1) = '.' then
3624                return Name_Buffer (J .. Name_Len - 2);
3625             end if;
3626          end loop;
3627
3628          raise Program_Error; -- impossible exit
3629
3630       --  Case where "main" is to be used as default
3631
3632       else
3633          return "main";
3634       end if;
3635    end Get_Main_Name;
3636
3637    ---------------------
3638    -- Get_WC_Encoding --
3639    ---------------------
3640
3641    function Get_WC_Encoding return Character is
3642    begin
3643       --  If encoding method specified by -W switch, then return it
3644
3645       if Wide_Character_Encoding_Method_Specified then
3646          return WC_Encoding_Letters (Wide_Character_Encoding_Method);
3647
3648       --  If no main program, and not specified, set brackets, we really have
3649       --  no better choice. If some other encoding is required when there is
3650       --  no main, it must be set explicitly using -Wx.
3651
3652       --  Note: if the ALI file always passed the wide character encoding of
3653       --  every file, then we could use the encoding of the initial specified
3654       --  file, but this information is passed only for potential main
3655       --  programs. We could fix this sometime, but it is a very minor point
3656       --  (wide character default encoding for [Wide_[Wide_]Text_IO when there
3657       --  is no main program).
3658
3659       elsif No_Main_Subprogram then
3660          return 'b';
3661
3662       --  Otherwise if there is a main program, take encoding from it
3663
3664       else
3665          return ALIs.Table (ALIs.First).WC_Encoding;
3666       end if;
3667    end Get_WC_Encoding;
3668
3669    -------------------
3670    -- Has_Finalizer --
3671    -------------------
3672
3673    function Has_Finalizer return Boolean is
3674       U     : Unit_Record;
3675       Unum  : Unit_Id;
3676
3677    begin
3678       for E in reverse Elab_Order.First .. Elab_Order.Last loop
3679          Unum := Elab_Order.Table (E);
3680          U    := Units.Table (Unum);
3681
3682          --  We are only interested in non-generic packages
3683
3684          if U.Unit_Kind = 'p'
3685            and then U.Has_Finalizer
3686            and then not U.Is_Generic
3687            and then not U.No_Elab
3688          then
3689             return True;
3690          end if;
3691       end loop;
3692
3693       return False;
3694    end Has_Finalizer;
3695
3696    ----------------------
3697    -- Lt_Linker_Option --
3698    ----------------------
3699
3700    function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean is
3701    begin
3702       --  Sort internal files last
3703
3704       if Linker_Options.Table (Op1).Internal_File
3705            /=
3706          Linker_Options.Table (Op2).Internal_File
3707       then
3708          --  Note: following test uses False < True
3709
3710          return Linker_Options.Table (Op1).Internal_File
3711                   <
3712                 Linker_Options.Table (Op2).Internal_File;
3713
3714       --  If both internal or both non-internal, sort according to the
3715       --  elaboration position. A unit that is elaborated later should come
3716       --  earlier in the linker options list.
3717
3718       else
3719          return Units.Table (Linker_Options.Table (Op1).Unit).Elab_Position
3720                   >
3721                 Units.Table (Linker_Options.Table (Op2).Unit).Elab_Position;
3722
3723       end if;
3724    end Lt_Linker_Option;
3725
3726    ------------------------
3727    -- Move_Linker_Option --
3728    ------------------------
3729
3730    procedure Move_Linker_Option (From : Natural; To : Natural) is
3731    begin
3732       Linker_Options.Table (To) := Linker_Options.Table (From);
3733    end Move_Linker_Option;
3734
3735    ----------------------------
3736    -- Resolve_Binder_Options --
3737    ----------------------------
3738
3739    procedure Resolve_Binder_Options is
3740    begin
3741       for E in Elab_Order.First .. Elab_Order.Last loop
3742          Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
3743
3744          --  This is not a perfect approach, but is the current protocol
3745          --  between the run-time and the binder to indicate that tasking is
3746          --  used: system.os_interface should always be used by any tasking
3747          --  application.
3748
3749          if Name_Buffer (1 .. 19) = "system.os_interface" then
3750             With_GNARL := True;
3751          end if;
3752
3753          --  Ditto for declib and the "dec" package
3754
3755          if OpenVMS_On_Target and then Name_Buffer (1 .. 5) = "dec%s" then
3756             With_DECGNAT := True;
3757          end if;
3758       end loop;
3759    end Resolve_Binder_Options;
3760
3761    -----------------
3762    -- Set_Boolean --
3763    -----------------
3764
3765    procedure Set_Boolean (B : Boolean) is
3766       True_Str  : constant String := "True";
3767       False_Str : constant String := "False";
3768    begin
3769       if B then
3770          Statement_Buffer (Last + 1 .. Last + True_Str'Length) := True_Str;
3771          Last := Last + True_Str'Length;
3772       else
3773          Statement_Buffer (Last + 1 .. Last + False_Str'Length) := False_Str;
3774          Last := Last + False_Str'Length;
3775       end if;
3776    end Set_Boolean;
3777
3778    --------------
3779    -- Set_Char --
3780    --------------
3781
3782    procedure Set_Char (C : Character) is
3783    begin
3784       Last := Last + 1;
3785       Statement_Buffer (Last) := C;
3786    end Set_Char;
3787
3788    -------------
3789    -- Set_Int --
3790    -------------
3791
3792    procedure Set_Int (N : Int) is
3793    begin
3794       if N < 0 then
3795          Set_String ("-");
3796          Set_Int (-N);
3797
3798       else
3799          if N > 9 then
3800             Set_Int (N / 10);
3801          end if;
3802
3803          Last := Last + 1;
3804          Statement_Buffer (Last) :=
3805            Character'Val (N mod 10 + Character'Pos ('0'));
3806       end if;
3807    end Set_Int;
3808
3809    -------------------------
3810    -- Set_IS_Pragma_Table --
3811    -------------------------
3812
3813    procedure Set_IS_Pragma_Table is
3814    begin
3815       for F in ALIs.First .. ALIs.Last loop
3816          for K in ALIs.Table (F).First_Interrupt_State ..
3817                   ALIs.Table (F).Last_Interrupt_State
3818          loop
3819             declare
3820                Inum : constant Int :=
3821                         Interrupt_States.Table (K).Interrupt_Id;
3822                Stat : constant Character :=
3823                         Interrupt_States.Table (K).Interrupt_State;
3824
3825             begin
3826                while IS_Pragma_Settings.Last < Inum loop
3827                   IS_Pragma_Settings.Append ('n');
3828                end loop;
3829
3830                IS_Pragma_Settings.Table (Inum) := Stat;
3831             end;
3832          end loop;
3833       end loop;
3834    end Set_IS_Pragma_Table;
3835
3836    ---------------------------
3837    -- Set_Main_Program_Name --
3838    ---------------------------
3839
3840    procedure Set_Main_Program_Name is
3841    begin
3842       --  Note that name has %b on the end which we ignore
3843
3844       --  First we output the initial _ada_ since we know that the main
3845       --  program is a library level subprogram.
3846
3847       Set_String ("_ada_");
3848
3849       --  Copy name, changing dots to double underscores
3850
3851       for J in 1 .. Name_Len - 2 loop
3852          if Name_Buffer (J) = '.' then
3853             Set_String ("__");
3854          else
3855             Set_Char (Name_Buffer (J));
3856          end if;
3857       end loop;
3858    end Set_Main_Program_Name;
3859
3860    ---------------------
3861    -- Set_Name_Buffer --
3862    ---------------------
3863
3864    procedure Set_Name_Buffer is
3865    begin
3866       for J in 1 .. Name_Len loop
3867          Set_Char (Name_Buffer (J));
3868       end loop;
3869    end Set_Name_Buffer;
3870
3871    -------------------------
3872    -- Set_PSD_Pragma_Table --
3873    -------------------------
3874
3875    procedure Set_PSD_Pragma_Table is
3876    begin
3877       for F in ALIs.First .. ALIs.Last loop
3878          for K in ALIs.Table (F).First_Specific_Dispatching ..
3879                   ALIs.Table (F).Last_Specific_Dispatching
3880          loop
3881             declare
3882                DTK : Specific_Dispatching_Record
3883                        renames Specific_Dispatching.Table (K);
3884
3885             begin
3886                while PSD_Pragma_Settings.Last < DTK.Last_Priority loop
3887                   PSD_Pragma_Settings.Append ('F');
3888                end loop;
3889
3890                for Prio in DTK.First_Priority .. DTK.Last_Priority loop
3891                   PSD_Pragma_Settings.Table (Prio) := DTK.Dispatching_Policy;
3892                end loop;
3893             end;
3894          end loop;
3895       end loop;
3896    end Set_PSD_Pragma_Table;
3897
3898    ----------------
3899    -- Set_String --
3900    ----------------
3901
3902    procedure Set_String (S : String) is
3903    begin
3904       Statement_Buffer (Last + 1 .. Last + S'Length) := S;
3905       Last := Last + S'Length;
3906    end Set_String;
3907
3908    ------------------------
3909    -- Set_String_Replace --
3910    ------------------------
3911
3912    procedure Set_String_Replace (S : String) is
3913    begin
3914       Statement_Buffer (Last - S'Length + 1 .. Last) := S;
3915    end Set_String_Replace;
3916
3917    -------------------
3918    -- Set_Unit_Name --
3919    -------------------
3920
3921    procedure Set_Unit_Name (Mode : Qualification_Mode := Double_Underscores) is
3922    begin
3923       for J in 1 .. Name_Len - 2 loop
3924          if Name_Buffer (J) = '.' then
3925             if Mode = Double_Underscores then
3926                Set_String ("__");
3927             elsif Mode = Dot then
3928                Set_Char ('.');
3929             else
3930                Set_Char ('$');
3931             end if;
3932          else
3933             Set_Char (Name_Buffer (J));
3934          end if;
3935       end loop;
3936    end Set_Unit_Name;
3937
3938    ---------------------
3939    -- Set_Unit_Number --
3940    ---------------------
3941
3942    procedure Set_Unit_Number (U : Unit_Id) is
3943       Num_Units : constant Nat := Nat (Units.Last) - Nat (Unit_Id'First);
3944       Unum      : constant Nat := Nat (U) - Nat (Unit_Id'First);
3945
3946    begin
3947       if Num_Units >= 10 and then Unum < 10 then
3948          Set_Char ('0');
3949       end if;
3950
3951       if Num_Units >= 100 and then Unum < 100 then
3952          Set_Char ('0');
3953       end if;
3954
3955       Set_Int (Unum);
3956    end Set_Unit_Number;
3957
3958    ----------------------
3959    -- Write_Info_Ada_C --
3960    ----------------------
3961
3962    procedure Write_Info_Ada_C (Ada : String; C : String; Common : String) is
3963    begin
3964       if Ada_Bind_File then
3965          declare
3966             S : String (1 .. Ada'Length + Common'Length);
3967          begin
3968             S (1 .. Ada'Length) := Ada;
3969             S (Ada'Length + 1 .. S'Length) := Common;
3970             WBI (S);
3971          end;
3972
3973       else
3974          declare
3975             S : String (1 .. C'Length + Common'Length);
3976          begin
3977             S (1 .. C'Length) := C;
3978             S (C'Length + 1 .. S'Length) := Common;
3979             WBI (S);
3980          end;
3981       end if;
3982    end Write_Info_Ada_C;
3983
3984    ----------------------------
3985    -- Write_Statement_Buffer --
3986    ----------------------------
3987
3988    procedure Write_Statement_Buffer is
3989    begin
3990       WBI (Statement_Buffer (1 .. Last));
3991       Last := 0;
3992    end Write_Statement_Buffer;
3993
3994    procedure Write_Statement_Buffer (S : String) is
3995    begin
3996       Set_String (S);
3997       Write_Statement_Buffer;
3998    end Write_Statement_Buffer;
3999
4000 end Bindgen;