OSDN Git Service

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