OSDN Git Service

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