OSDN Git Service

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