OSDN Git Service

* gcc-interface/trans.c (lhs_or_actual_p): New predicate.
[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             end if;
1897          end if;
1898       end loop;
1899
1900       if Object_List_Filename /= null then
1901          Close_List_File;
1902       end if;
1903
1904       --  Add a "-Ldir" for each directory in the object path
1905       if VM_Target /= CLI_Target then
1906          for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
1907             declare
1908                Dir : constant String_Ptr := Dir_In_Obj_Search_Path (J);
1909             begin
1910                Name_Len := 0;
1911                Add_Str_To_Name_Buffer ("-L");
1912                Add_Str_To_Name_Buffer (Dir.all);
1913                Write_Linker_Option;
1914             end;
1915          end loop;
1916       end if;
1917
1918       --  Sort linker options
1919
1920       --  This sort accomplishes two important purposes:
1921
1922       --    a) All application files are sorted to the front, and all GNAT
1923       --       internal files are sorted to the end. This results in a well
1924       --       defined dividing line between the two sets of files, for the
1925       --       purpose of inserting certain standard library references into
1926       --       the linker arguments list.
1927
1928       --    b) Given two different units, we sort the linker options so that
1929       --       those from a unit earlier in the elaboration order comes later
1930       --       in the list. This is a heuristic designed to create a more
1931       --       friendly order of linker options when the operations appear in
1932       --       separate units. The idea is that if unit A must be elaborated
1933       --       before unit B, then it is more likely that B references
1934       --       libraries included by A, than vice versa, so we want libraries
1935       --       included by A to come after libraries included by B.
1936
1937       --  These two criteria are implemented by function Lt_Linker_Option. Note
1938       --  that a special case of b) is that specs are elaborated before bodies,
1939       --  so linker options from specs come after linker options for bodies,
1940       --  and again, the assumption is that libraries used by the body are more
1941       --  likely to reference libraries used by the spec, than vice versa.
1942
1943       Sort
1944         (Linker_Options.Last,
1945          Move_Linker_Option'Access,
1946          Lt_Linker_Option'Access);
1947
1948       --  Write user linker options, i.e. the set of linker options that come
1949       --  from all files other than GNAT internal files, Lgnat is left set to
1950       --  point to the first entry from a GNAT internal file, or past the end
1951       --  of the entries if there are no internal files.
1952
1953       Lgnat := Linker_Options.Last + 1;
1954
1955       for J in 1 .. Linker_Options.Last loop
1956          if not Linker_Options.Table (J).Internal_File then
1957             Get_Name_String (Linker_Options.Table (J).Name);
1958             Write_Linker_Option;
1959          else
1960             Lgnat := J;
1961             exit;
1962          end if;
1963       end loop;
1964
1965       --  Now we insert standard linker options that must appear after the
1966       --  entries from user files, and before the entries from GNAT run-time
1967       --  files. The reason for this decision is that libraries referenced
1968       --  by internal routines may reference these standard library entries.
1969
1970       --  Note that we do not insert anything when pragma No_Run_Time has been
1971       --  specified or when the standard libraries are not to be used,
1972       --  otherwise on some platforms, such as VMS, we may get duplicate
1973       --  symbols when linking.
1974
1975       if not (Opt.No_Run_Time_Mode or else Opt.No_Stdlib) then
1976          Name_Len := 0;
1977
1978          if Opt.Shared_Libgnat then
1979             Add_Str_To_Name_Buffer ("-shared");
1980          else
1981             Add_Str_To_Name_Buffer ("-static");
1982          end if;
1983
1984          --  Write directly to avoid -K output (why???)
1985
1986          WBI ("   --   " & Name_Buffer (1 .. Name_Len));
1987
1988          if With_DECGNAT then
1989             Name_Len := 0;
1990
1991             if Opt.Shared_Libgnat then
1992                Add_Str_To_Name_Buffer (Shared_Lib ("decgnat"));
1993             else
1994                Add_Str_To_Name_Buffer ("-ldecgnat");
1995             end if;
1996
1997             Write_Linker_Option;
1998          end if;
1999
2000          if With_GNARL then
2001             Name_Len := 0;
2002
2003             if Opt.Shared_Libgnat then
2004                Add_Str_To_Name_Buffer (Shared_Lib ("gnarl"));
2005             else
2006                Add_Str_To_Name_Buffer ("-lgnarl");
2007             end if;
2008
2009             Write_Linker_Option;
2010          end if;
2011
2012          Name_Len := 0;
2013
2014          if Opt.Shared_Libgnat then
2015             Add_Str_To_Name_Buffer (Shared_Lib ("gnat"));
2016          else
2017             Add_Str_To_Name_Buffer ("-lgnat");
2018          end if;
2019
2020          Write_Linker_Option;
2021       end if;
2022
2023       --  Write linker options from all internal files
2024
2025       for J in Lgnat .. Linker_Options.Last loop
2026          Get_Name_String (Linker_Options.Table (J).Name);
2027          Write_Linker_Option;
2028       end loop;
2029
2030       if Output_Linker_Option_List and then not Zero_Formatting then
2031          Write_Eol;
2032       end if;
2033
2034       WBI ("--  END Object file/option list   ");
2035    end Gen_Object_Files_Options;
2036
2037    ---------------------
2038    -- Gen_Output_File --
2039    ---------------------
2040
2041    procedure Gen_Output_File (Filename : String) is
2042    begin
2043       --  Acquire settings for Interrupt_State pragmas
2044
2045       Set_IS_Pragma_Table;
2046
2047       --  Acquire settings for Priority_Specific_Dispatching pragma
2048
2049       Set_PSD_Pragma_Table;
2050
2051       --  For JGNAT the main program is already generated by the compiler
2052
2053       if VM_Target = JVM_Target then
2054          Bind_Main_Program := False;
2055       end if;
2056
2057       --  Override time slice value if -T switch is set
2058
2059       if Time_Slice_Set then
2060          ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value;
2061       end if;
2062
2063       --  Count number of elaboration calls
2064
2065       for E in Elab_Order.First .. Elab_Order.Last loop
2066          if Units.Table (Elab_Order.Table (E)).No_Elab then
2067             null;
2068          else
2069             Num_Elab_Calls := Num_Elab_Calls + 1;
2070          end if;
2071       end loop;
2072
2073       --  Generate output file in appropriate language
2074
2075       Check_System_Restrictions_Used;
2076       Check_Dispatching_Domains_Used;
2077
2078       Gen_Output_File_Ada (Filename);
2079    end Gen_Output_File;
2080
2081    -------------------------
2082    -- Gen_Output_File_Ada --
2083    -------------------------
2084
2085    procedure Gen_Output_File_Ada (Filename : String) is
2086
2087       Ada_Main : constant String := Get_Ada_Main_Name;
2088       --  Name to be used for generated Ada main program. See the body of
2089       --  function Get_Ada_Main_Name for details on the form of the name.
2090
2091       Needs_Library_Finalization : constant Boolean :=
2092                                      not Configurable_Run_Time_On_Target
2093                                        and then Has_Finalizer;
2094       --  For restricted run-time libraries (ZFP and Ravenscar) tasks are
2095       --  non-terminating, so we do not want finalization.
2096
2097       Bfiles : Name_Id;
2098       --  Name of generated bind file (spec)
2099
2100       Bfileb : Name_Id;
2101       --  Name of generated bind file (body)
2102
2103    begin
2104       --  Create spec first
2105
2106       Create_Binder_Output (Filename, 's', Bfiles);
2107
2108       --  We always compile the binder file in Ada 95 mode so that we properly
2109       --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2110       --  of the Ada 2005 or Ada 2012 constructs are needed by the binder file.
2111
2112       WBI ("pragma Ada_95;");
2113
2114       --  If we are operating in Restrictions (No_Exception_Handlers) mode,
2115       --  then we need to make sure that the binder program is compiled with
2116       --  the same restriction, so that no exception tables are generated.
2117
2118       if Cumulative_Restrictions.Set (No_Exception_Handlers) then
2119          WBI ("pragma Restrictions (No_Exception_Handlers);");
2120       end if;
2121
2122       --  Same processing for Restrictions (No_Exception_Propagation)
2123
2124       if Cumulative_Restrictions.Set (No_Exception_Propagation) then
2125          WBI ("pragma Restrictions (No_Exception_Propagation);");
2126       end if;
2127
2128       --  Same processing for pragma No_Run_Time
2129
2130       if No_Run_Time_Mode then
2131          WBI ("pragma No_Run_Time;");
2132       end if;
2133
2134       --  Generate with of System so we can reference System.Address
2135
2136       WBI ("with System;");
2137
2138       --  Generate with of System.Initialize_Scalars if active
2139
2140       if Initialize_Scalars_Used then
2141          WBI ("with System.Scalar_Values;");
2142       end if;
2143
2144       --  Generate with of System.Secondary_Stack if active
2145
2146       if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
2147          WBI ("with System.Secondary_Stack;");
2148       end if;
2149
2150       Resolve_Binder_Options;
2151
2152       --  Usually, adafinal is called using a pragma Import C. Since Import C
2153       --  doesn't have the same semantics for VMs or CodePeer use standard Ada.
2154
2155       if not Suppress_Standard_Library_On_Target then
2156          if CodePeer_Mode then
2157             WBI ("with System.Standard_Library;");
2158          elsif VM_Target /= No_VM then
2159             WBI ("with System.Soft_Links;");
2160             WBI ("with System.Standard_Library;");
2161          end if;
2162       end if;
2163
2164       WBI ("package " & Ada_Main & " is");
2165       WBI ("   pragma Warnings (Off);");
2166
2167       --  Main program case
2168
2169       if Bind_Main_Program then
2170          if VM_Target = No_VM then
2171
2172             --  Generate argc/argv stuff unless suppressed
2173
2174             if Command_Line_Args_On_Target
2175               or not Configurable_Run_Time_On_Target
2176             then
2177                WBI ("");
2178                WBI ("   gnat_argc : Integer;");
2179                WBI ("   gnat_argv : System.Address;");
2180                WBI ("   gnat_envp : System.Address;");
2181
2182                --  If the standard library is not suppressed, these variables
2183                --  are in the run-time data area for easy run time access.
2184
2185                if not Suppress_Standard_Library_On_Target then
2186                   WBI ("");
2187                   WBI ("   pragma Import (C, gnat_argc);");
2188                   WBI ("   pragma Import (C, gnat_argv);");
2189                   WBI ("   pragma Import (C, gnat_envp);");
2190                end if;
2191             end if;
2192
2193             --  Define exit status. Again in normal mode, this is in the
2194             --  run-time library, and is initialized there, but in the
2195             --  configurable runtime case, the variable is declared and
2196             --  initialized in this file.
2197
2198             WBI ("");
2199
2200             if Configurable_Run_Time_Mode then
2201                if Exit_Status_Supported_On_Target then
2202                   WBI ("   gnat_exit_status : Integer := 0;");
2203                end if;
2204
2205             else
2206                WBI ("   gnat_exit_status : Integer;");
2207                WBI ("   pragma Import (C, gnat_exit_status);");
2208             end if;
2209          end if;
2210
2211          --  Generate the GNAT_Version and Ada_Main_Program_Name info only for
2212          --  the main program. Otherwise, it can lead under some circumstances
2213          --  to a symbol duplication during the link (for instance when a C
2214          --  program uses two Ada libraries). Also zero terminate the string
2215          --  so that its end can be found reliably at run time.
2216
2217          WBI ("");
2218          WBI ("   GNAT_Version : constant String :=");
2219          WBI ("                    """ & Ver_Prefix &
2220                                    Gnat_Version_String &
2221                                    """ & ASCII.NUL;");
2222          WBI ("   pragma Export (C, GNAT_Version, ""__gnat_version"");");
2223
2224          WBI ("");
2225          Set_String ("   Ada_Main_Program_Name : constant String := """);
2226          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2227
2228          if VM_Target = No_VM then
2229             Set_Main_Program_Name;
2230             Set_String (""" & ASCII.NUL;");
2231          else
2232             Set_String (Name_Buffer (1 .. Name_Len - 2) & """;");
2233          end if;
2234
2235          Write_Statement_Buffer;
2236
2237          WBI
2238            ("   pragma Export (C, Ada_Main_Program_Name, " &
2239             """__gnat_ada_main_program_name"");");
2240       end if;
2241
2242       WBI ("");
2243       WBI ("   procedure " & Ada_Init_Name.all & ";");
2244       WBI ("   pragma Export (C, " & Ada_Init_Name.all & ", """ &
2245            Ada_Init_Name.all & """);");
2246
2247       --  If -a has been specified use pragma Linker_Constructor for the init
2248       --  procedure and pragma Linker_Destructor for the final procedure.
2249
2250       if Use_Pragma_Linker_Constructor then
2251          WBI ("   pragma Linker_Constructor (" & Ada_Init_Name.all & ");");
2252       end if;
2253
2254       if not Cumulative_Restrictions.Set (No_Finalization) then
2255          WBI ("");
2256          WBI ("   procedure " & Ada_Final_Name.all & ";");
2257          WBI ("   pragma Export (C, " & Ada_Final_Name.all & ", """ &
2258               Ada_Final_Name.all & """);");
2259
2260          if Use_Pragma_Linker_Constructor then
2261             WBI ("   pragma Linker_Destructor (" & Ada_Final_Name.all & ");");
2262          end if;
2263       end if;
2264
2265       if Bind_Main_Program and then VM_Target = No_VM then
2266
2267          WBI ("");
2268
2269          if Exit_Status_Supported_On_Target then
2270             Set_String ("   function ");
2271          else
2272             Set_String ("   procedure ");
2273          end if;
2274
2275          Set_String (Get_Main_Name);
2276
2277          --  Generate argument list if present
2278
2279          if Command_Line_Args_On_Target then
2280             Write_Statement_Buffer;
2281             WBI ("     (argc : Integer;");
2282             WBI ("      argv : System.Address;");
2283             Set_String
2284                 ("      envp : System.Address)");
2285
2286             if Exit_Status_Supported_On_Target then
2287                Write_Statement_Buffer;
2288                WBI ("      return Integer;");
2289             else
2290                Write_Statement_Buffer (";");
2291             end if;
2292
2293          else
2294             if Exit_Status_Supported_On_Target then
2295                Write_Statement_Buffer (" return Integer;");
2296             else
2297                Write_Statement_Buffer (";");
2298             end if;
2299          end if;
2300
2301          WBI ("   pragma Export (C, " & Get_Main_Name & ", """ &
2302            Get_Main_Name & """);");
2303       end if;
2304
2305       Gen_Versions;
2306       Gen_Elab_Order;
2307
2308       --  Spec is complete
2309
2310       WBI ("");
2311       WBI ("end " & Ada_Main & ";");
2312       Close_Binder_Output;
2313
2314       --  Prepare to write body
2315
2316       Create_Binder_Output (Filename, 'b', Bfileb);
2317
2318       --  We always compile the binder file in Ada 95 mode so that we properly
2319       --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2320       --  of the Ada 2005/2012 constructs are needed by the binder file.
2321
2322       WBI ("pragma Ada_95;");
2323
2324       --  Output Source_File_Name pragmas which look like
2325
2326       --    pragma Source_File_Name (Ada_Main, Spec_File_Name => "sss");
2327       --    pragma Source_File_Name (Ada_Main, Body_File_Name => "bbb");
2328
2329       --  where sss/bbb are the spec/body file names respectively
2330
2331       Get_Name_String (Bfiles);
2332       Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2333
2334       WBI ("pragma Source_File_Name (" &
2335            Ada_Main &
2336            ", Spec_File_Name => """ &
2337            Name_Buffer (1 .. Name_Len + 3));
2338
2339       Get_Name_String (Bfileb);
2340       Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2341
2342       WBI ("pragma Source_File_Name (" &
2343            Ada_Main &
2344            ", Body_File_Name => """ &
2345            Name_Buffer (1 .. Name_Len + 3));
2346
2347       --  Generate with of System.Restrictions to initialize
2348       --  Run_Time_Restrictions.
2349
2350       if System_Restrictions_Used
2351         and not Suppress_Standard_Library_On_Target
2352       then
2353          WBI ("");
2354          WBI ("with System.Restrictions;");
2355       end if;
2356
2357       if Needs_Library_Finalization then
2358          WBI ("with Ada.Exceptions;");
2359       end if;
2360
2361       WBI ("");
2362       WBI ("package body " & Ada_Main & " is");
2363       WBI ("   pragma Warnings (Off);");
2364       WBI ("");
2365
2366       --  Generate externals for elaboration entities
2367
2368       Gen_Elab_Externals;
2369
2370       if not CodePeer_Mode then
2371          if not Suppress_Standard_Library_On_Target then
2372
2373             --  Generate Priority_Specific_Dispatching pragma string
2374
2375             Set_String
2376               ("   Local_Priority_Specific_Dispatching : " &
2377                "constant String := """);
2378
2379             for J in 0 .. PSD_Pragma_Settings.Last loop
2380                Set_Char (PSD_Pragma_Settings.Table (J));
2381             end loop;
2382
2383             Set_String (""";");
2384             Write_Statement_Buffer;
2385
2386             --  Generate Interrupt_State pragma string
2387
2388             Set_String ("   Local_Interrupt_States : constant String := """);
2389
2390             for J in 0 .. IS_Pragma_Settings.Last loop
2391                Set_Char (IS_Pragma_Settings.Table (J));
2392             end loop;
2393
2394             Set_String (""";");
2395             Write_Statement_Buffer;
2396             WBI ("");
2397          end if;
2398
2399          --  The B.1 (39) implementation advice says that the adainit/adafinal
2400          --  routines should be idempotent. Generate a flag to ensure that.
2401
2402          WBI ("   Is_Elaborated : Boolean := False;");
2403          WBI ("");
2404       end if;
2405
2406       --  Generate the adafinal routine unless there is no finalization to do
2407
2408       if not Cumulative_Restrictions.Set (No_Finalization) then
2409          if Needs_Library_Finalization then
2410             Gen_Finalize_Library;
2411          end if;
2412
2413          Gen_Adafinal;
2414       end if;
2415
2416       Gen_Adainit;
2417
2418       if Bind_Main_Program and then VM_Target = No_VM then
2419          Gen_Main;
2420       end if;
2421
2422       --  Output object file list and the Ada body is complete
2423
2424       Gen_Object_Files_Options;
2425
2426       WBI ("");
2427       WBI ("end " & Ada_Main & ";");
2428
2429       Close_Binder_Output;
2430    end Gen_Output_File_Ada;
2431
2432    ----------------------
2433    -- Gen_Restrictions --
2434    ----------------------
2435
2436    procedure Gen_Restrictions is
2437       Count : Integer;
2438
2439    begin
2440       if Suppress_Standard_Library_On_Target
2441         or not System_Restrictions_Used
2442       then
2443          return;
2444       end if;
2445
2446       WBI ("      System.Restrictions.Run_Time_Restrictions :=");
2447       WBI ("        (Set =>");
2448       Set_String      ("          (");
2449
2450       Count := 0;
2451
2452       for J in Cumulative_Restrictions.Set'Range loop
2453          Set_Boolean (Cumulative_Restrictions.Set (J));
2454          Set_String (", ");
2455          Count := Count + 1;
2456
2457          if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2458             Write_Statement_Buffer;
2459             Set_String ("           ");
2460             Count := 0;
2461          end if;
2462       end loop;
2463
2464       Set_String_Replace ("),");
2465       Write_Statement_Buffer;
2466       Set_String ("         Value => (");
2467
2468       for J in Cumulative_Restrictions.Value'Range loop
2469          Set_Int (Int (Cumulative_Restrictions.Value (J)));
2470          Set_String (", ");
2471       end loop;
2472
2473       Set_String_Replace ("),");
2474       Write_Statement_Buffer;
2475       WBI ("         Violated =>");
2476       Set_String ("          (");
2477       Count := 0;
2478
2479       for J in Cumulative_Restrictions.Violated'Range loop
2480          Set_Boolean (Cumulative_Restrictions.Violated (J));
2481          Set_String (", ");
2482          Count := Count + 1;
2483
2484          if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2485             Write_Statement_Buffer;
2486             Set_String ("           ");
2487             Count := 0;
2488          end if;
2489       end loop;
2490
2491       Set_String_Replace ("),");
2492       Write_Statement_Buffer;
2493       Set_String ("         Count => (");
2494
2495       for J in Cumulative_Restrictions.Count'Range loop
2496          Set_Int (Int (Cumulative_Restrictions.Count (J)));
2497          Set_String (", ");
2498       end loop;
2499
2500       Set_String_Replace ("),");
2501       Write_Statement_Buffer;
2502       Set_String ("         Unknown => (");
2503
2504       for J in Cumulative_Restrictions.Unknown'Range loop
2505          Set_Boolean (Cumulative_Restrictions.Unknown (J));
2506          Set_String (", ");
2507       end loop;
2508
2509       Set_String_Replace ("))");
2510       Set_String (";");
2511       Write_Statement_Buffer;
2512    end Gen_Restrictions;
2513
2514    ------------------
2515    -- Gen_Versions --
2516    ------------------
2517
2518    --  This routine generates lines such as:
2519
2520    --    unnnnn : constant Integer := 16#hhhhhhhh#;
2521    --    pragma Export (C, unnnnn, unam);
2522
2523    --  for each unit, where unam is the unit name suffixed by either B or S for
2524    --  body or spec, with dots replaced by double underscores, and hhhhhhhh is
2525    --  the version number, and nnnnn is a 5-digits serial number.
2526
2527    procedure Gen_Versions is
2528       Ubuf : String (1 .. 6) := "u00000";
2529
2530       procedure Increment_Ubuf;
2531       --  Little procedure to increment the serial number
2532
2533       --------------------
2534       -- Increment_Ubuf --
2535       --------------------
2536
2537       procedure Increment_Ubuf is
2538       begin
2539          for J in reverse Ubuf'Range loop
2540             Ubuf (J) := Character'Succ (Ubuf (J));
2541             exit when Ubuf (J) <= '9';
2542             Ubuf (J) := '0';
2543          end loop;
2544       end Increment_Ubuf;
2545
2546    --  Start of processing for Gen_Versions
2547
2548    begin
2549       WBI ("");
2550
2551       WBI ("   type Version_32 is mod 2 ** 32;");
2552       for U in Units.First .. Units.Last loop
2553          if not Units.Table (U).SAL_Interface
2554            and then
2555              (not Bind_For_Library or else Units.Table (U).Directly_Scanned)
2556          then
2557             Increment_Ubuf;
2558             WBI ("   " & Ubuf & " : constant Version_32 := 16#" &
2559                  Units.Table (U).Version & "#;");
2560             Set_String ("   pragma Export (C, ");
2561             Set_String (Ubuf);
2562             Set_String (", """);
2563
2564             Get_Name_String (Units.Table (U).Uname);
2565
2566             for K in 1 .. Name_Len loop
2567                if Name_Buffer (K) = '.' then
2568                   Set_Char ('_');
2569                   Set_Char ('_');
2570
2571                elsif Name_Buffer (K) = '%' then
2572                   exit;
2573
2574                else
2575                   Set_Char (Name_Buffer (K));
2576                end if;
2577             end loop;
2578
2579             if Name_Buffer (Name_Len) = 's' then
2580                Set_Char ('S');
2581             else
2582                Set_Char ('B');
2583             end if;
2584
2585             Set_String (""");");
2586             Write_Statement_Buffer;
2587          end if;
2588       end loop;
2589    end Gen_Versions;
2590
2591    ------------------------
2592    -- Get_Main_Unit_Name --
2593    ------------------------
2594
2595    function Get_Main_Unit_Name (S : String) return String is
2596       Result : String := S;
2597
2598    begin
2599       for J in S'Range loop
2600          if Result (J) = '.' then
2601             Result (J) := '_';
2602          end if;
2603       end loop;
2604
2605       return Result;
2606    end Get_Main_Unit_Name;
2607
2608    -----------------------
2609    -- Get_Ada_Main_Name --
2610    -----------------------
2611
2612    function Get_Ada_Main_Name return String is
2613       Suffix : constant String := "_00";
2614       Name   : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
2615                  Opt.Ada_Main_Name.all & Suffix;
2616       Nlen   : Natural;
2617
2618    begin
2619       --  The main program generated by JGNAT expects a package called
2620       --  ada_<main procedure>.
2621       if VM_Target /= No_VM then
2622          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2623          return "ada_" & Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
2624       end if;
2625
2626       --  For CodePeer, we want reproducible names (independent of other
2627       --  mains that may or may not be present) that don't collide
2628       --  when analyzing multiple mains and which are easily recognizable
2629       --  as "ada_main" names.
2630       if CodePeer_Mode then
2631          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2632          return "ada_main_for_" &
2633            Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
2634       end if;
2635
2636       --  This loop tries the following possibilities in order
2637       --    <Ada_Main>
2638       --    <Ada_Main>_01
2639       --    <Ada_Main>_02
2640       --    ..
2641       --    <Ada_Main>_99
2642       --  where <Ada_Main> is equal to Opt.Ada_Main_Name. By default,
2643       --  it is set to 'ada_main'.
2644
2645       for J in 0 .. 99 loop
2646          if J = 0 then
2647             Nlen := Name'Length - Suffix'Length;
2648          else
2649             Nlen := Name'Length;
2650             Name (Name'Last) := Character'Val (J mod 10 + Character'Pos ('0'));
2651             Name (Name'Last - 1) :=
2652               Character'Val (J /   10 + Character'Pos ('0'));
2653          end if;
2654
2655          for K in ALIs.First .. ALIs.Last loop
2656             for L in ALIs.Table (K).First_Unit .. ALIs.Table (K).Last_Unit loop
2657
2658                --  Get unit name, removing %b or %e at end
2659
2660                Get_Name_String (Units.Table (L).Uname);
2661                Name_Len := Name_Len - 2;
2662
2663                if Name_Buffer (1 .. Name_Len) = Name (1 .. Nlen) then
2664                   goto Continue;
2665                end if;
2666             end loop;
2667          end loop;
2668
2669          return Name (1 .. Nlen);
2670
2671       <<Continue>>
2672          null;
2673       end loop;
2674
2675       --  If we fall through, just use a peculiar unlikely name
2676
2677       return ("Qwertyuiop");
2678    end Get_Ada_Main_Name;
2679
2680    -------------------
2681    -- Get_Main_Name --
2682    -------------------
2683
2684    function Get_Main_Name return String is
2685    begin
2686       --  Explicit name given with -M switch
2687
2688       if Bind_Alternate_Main_Name then
2689          return Alternate_Main_Name.all;
2690
2691       --  Case of main program name to be used directly
2692
2693       elsif Use_Ada_Main_Program_Name_On_Target then
2694
2695          --  Get main program name
2696
2697          Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2698
2699          --  If this is a child name, return only the name of the child, since
2700          --  we can't have dots in a nested program name. Note that we do not
2701          --  include the %b at the end of the unit name.
2702
2703          for J in reverse 1 .. Name_Len - 2 loop
2704             if J = 1 or else Name_Buffer (J - 1) = '.' then
2705                return Name_Buffer (J .. Name_Len - 2);
2706             end if;
2707          end loop;
2708
2709          raise Program_Error; -- impossible exit
2710
2711       --  Case where "main" is to be used as default
2712
2713       else
2714          return "main";
2715       end if;
2716    end Get_Main_Name;
2717
2718    ---------------------
2719    -- Get_WC_Encoding --
2720    ---------------------
2721
2722    function Get_WC_Encoding return Character is
2723    begin
2724       --  If encoding method specified by -W switch, then return it
2725
2726       if Wide_Character_Encoding_Method_Specified then
2727          return WC_Encoding_Letters (Wide_Character_Encoding_Method);
2728
2729       --  If no main program, and not specified, set brackets, we really have
2730       --  no better choice. If some other encoding is required when there is
2731       --  no main, it must be set explicitly using -Wx.
2732
2733       --  Note: if the ALI file always passed the wide character encoding of
2734       --  every file, then we could use the encoding of the initial specified
2735       --  file, but this information is passed only for potential main
2736       --  programs. We could fix this sometime, but it is a very minor point
2737       --  (wide character default encoding for [Wide_[Wide_]Text_IO when there
2738       --  is no main program).
2739
2740       elsif No_Main_Subprogram then
2741          return 'b';
2742
2743       --  Otherwise if there is a main program, take encoding from it
2744
2745       else
2746          return ALIs.Table (ALIs.First).WC_Encoding;
2747       end if;
2748    end Get_WC_Encoding;
2749
2750    -------------------
2751    -- Has_Finalizer --
2752    -------------------
2753
2754    function Has_Finalizer return Boolean is
2755       U     : Unit_Record;
2756       Unum  : Unit_Id;
2757
2758    begin
2759       for E in reverse Elab_Order.First .. Elab_Order.Last loop
2760          Unum := Elab_Order.Table (E);
2761          U    := Units.Table (Unum);
2762
2763          --  We are only interested in non-generic packages
2764
2765          if U.Unit_Kind = 'p'
2766            and then U.Has_Finalizer
2767            and then not U.Is_Generic
2768            and then not U.No_Elab
2769          then
2770             return True;
2771          end if;
2772       end loop;
2773
2774       return False;
2775    end Has_Finalizer;
2776
2777    ----------------------
2778    -- Lt_Linker_Option --
2779    ----------------------
2780
2781    function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean is
2782    begin
2783       --  Sort internal files last
2784
2785       if Linker_Options.Table (Op1).Internal_File
2786            /=
2787          Linker_Options.Table (Op2).Internal_File
2788       then
2789          --  Note: following test uses False < True
2790
2791          return Linker_Options.Table (Op1).Internal_File
2792                   <
2793                 Linker_Options.Table (Op2).Internal_File;
2794
2795       --  If both internal or both non-internal, sort according to the
2796       --  elaboration position. A unit that is elaborated later should come
2797       --  earlier in the linker options list.
2798
2799       else
2800          return Units.Table (Linker_Options.Table (Op1).Unit).Elab_Position
2801                   >
2802                 Units.Table (Linker_Options.Table (Op2).Unit).Elab_Position;
2803
2804       end if;
2805    end Lt_Linker_Option;
2806
2807    ------------------------
2808    -- Move_Linker_Option --
2809    ------------------------
2810
2811    procedure Move_Linker_Option (From : Natural; To : Natural) is
2812    begin
2813       Linker_Options.Table (To) := Linker_Options.Table (From);
2814    end Move_Linker_Option;
2815
2816    ----------------------------
2817    -- Resolve_Binder_Options --
2818    ----------------------------
2819
2820    procedure Resolve_Binder_Options is
2821    begin
2822       for E in Elab_Order.First .. Elab_Order.Last loop
2823          Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
2824
2825          --  This is not a perfect approach, but is the current protocol
2826          --  between the run-time and the binder to indicate that tasking is
2827          --  used: system.os_interface should always be used by any tasking
2828          --  application.
2829
2830          if Name_Buffer (1 .. 19) = "system.os_interface" then
2831             With_GNARL := True;
2832          end if;
2833
2834          --  Ditto for declib and the "dec" package
2835
2836          if OpenVMS_On_Target and then Name_Buffer (1 .. 5) = "dec%s" then
2837             With_DECGNAT := True;
2838          end if;
2839       end loop;
2840    end Resolve_Binder_Options;
2841
2842    -----------------
2843    -- Set_Boolean --
2844    -----------------
2845
2846    procedure Set_Boolean (B : Boolean) is
2847       True_Str  : constant String := "True";
2848       False_Str : constant String := "False";
2849    begin
2850       if B then
2851          Statement_Buffer (Last + 1 .. Last + True_Str'Length) := True_Str;
2852          Last := Last + True_Str'Length;
2853       else
2854          Statement_Buffer (Last + 1 .. Last + False_Str'Length) := False_Str;
2855          Last := Last + False_Str'Length;
2856       end if;
2857    end Set_Boolean;
2858
2859    --------------
2860    -- Set_Char --
2861    --------------
2862
2863    procedure Set_Char (C : Character) is
2864    begin
2865       Last := Last + 1;
2866       Statement_Buffer (Last) := C;
2867    end Set_Char;
2868
2869    -------------
2870    -- Set_Int --
2871    -------------
2872
2873    procedure Set_Int (N : Int) is
2874    begin
2875       if N < 0 then
2876          Set_String ("-");
2877          Set_Int (-N);
2878
2879       else
2880          if N > 9 then
2881             Set_Int (N / 10);
2882          end if;
2883
2884          Last := Last + 1;
2885          Statement_Buffer (Last) :=
2886            Character'Val (N mod 10 + Character'Pos ('0'));
2887       end if;
2888    end Set_Int;
2889
2890    -------------------------
2891    -- Set_IS_Pragma_Table --
2892    -------------------------
2893
2894    procedure Set_IS_Pragma_Table is
2895    begin
2896       for F in ALIs.First .. ALIs.Last loop
2897          for K in ALIs.Table (F).First_Interrupt_State ..
2898                   ALIs.Table (F).Last_Interrupt_State
2899          loop
2900             declare
2901                Inum : constant Int :=
2902                         Interrupt_States.Table (K).Interrupt_Id;
2903                Stat : constant Character :=
2904                         Interrupt_States.Table (K).Interrupt_State;
2905
2906             begin
2907                while IS_Pragma_Settings.Last < Inum loop
2908                   IS_Pragma_Settings.Append ('n');
2909                end loop;
2910
2911                IS_Pragma_Settings.Table (Inum) := Stat;
2912             end;
2913          end loop;
2914       end loop;
2915    end Set_IS_Pragma_Table;
2916
2917    ---------------------------
2918    -- Set_Main_Program_Name --
2919    ---------------------------
2920
2921    procedure Set_Main_Program_Name is
2922    begin
2923       --  Note that name has %b on the end which we ignore
2924
2925       --  First we output the initial _ada_ since we know that the main
2926       --  program is a library level subprogram.
2927
2928       Set_String ("_ada_");
2929
2930       --  Copy name, changing dots to double underscores
2931
2932       for J in 1 .. Name_Len - 2 loop
2933          if Name_Buffer (J) = '.' then
2934             Set_String ("__");
2935          else
2936             Set_Char (Name_Buffer (J));
2937          end if;
2938       end loop;
2939    end Set_Main_Program_Name;
2940
2941    ---------------------
2942    -- Set_Name_Buffer --
2943    ---------------------
2944
2945    procedure Set_Name_Buffer is
2946    begin
2947       for J in 1 .. Name_Len loop
2948          Set_Char (Name_Buffer (J));
2949       end loop;
2950    end Set_Name_Buffer;
2951
2952    -------------------------
2953    -- Set_PSD_Pragma_Table --
2954    -------------------------
2955
2956    procedure Set_PSD_Pragma_Table is
2957    begin
2958       for F in ALIs.First .. ALIs.Last loop
2959          for K in ALIs.Table (F).First_Specific_Dispatching ..
2960                   ALIs.Table (F).Last_Specific_Dispatching
2961          loop
2962             declare
2963                DTK : Specific_Dispatching_Record
2964                        renames Specific_Dispatching.Table (K);
2965
2966             begin
2967                while PSD_Pragma_Settings.Last < DTK.Last_Priority loop
2968                   PSD_Pragma_Settings.Append ('F');
2969                end loop;
2970
2971                for Prio in DTK.First_Priority .. DTK.Last_Priority loop
2972                   PSD_Pragma_Settings.Table (Prio) := DTK.Dispatching_Policy;
2973                end loop;
2974             end;
2975          end loop;
2976       end loop;
2977    end Set_PSD_Pragma_Table;
2978
2979    ----------------
2980    -- Set_String --
2981    ----------------
2982
2983    procedure Set_String (S : String) is
2984    begin
2985       Statement_Buffer (Last + 1 .. Last + S'Length) := S;
2986       Last := Last + S'Length;
2987    end Set_String;
2988
2989    ------------------------
2990    -- Set_String_Replace --
2991    ------------------------
2992
2993    procedure Set_String_Replace (S : String) is
2994    begin
2995       Statement_Buffer (Last - S'Length + 1 .. Last) := S;
2996    end Set_String_Replace;
2997
2998    -------------------
2999    -- Set_Unit_Name --
3000    -------------------
3001
3002    procedure Set_Unit_Name (Mode : Qualification_Mode := Double_Underscores) is
3003    begin
3004       for J in 1 .. Name_Len - 2 loop
3005          if Name_Buffer (J) = '.' then
3006             if Mode = Double_Underscores then
3007                Set_String ("__");
3008             elsif Mode = Dot then
3009                Set_Char ('.');
3010             else
3011                Set_Char ('$');
3012             end if;
3013          else
3014             Set_Char (Name_Buffer (J));
3015          end if;
3016       end loop;
3017    end Set_Unit_Name;
3018
3019    ---------------------
3020    -- Set_Unit_Number --
3021    ---------------------
3022
3023    procedure Set_Unit_Number (U : Unit_Id) is
3024       Num_Units : constant Nat := Nat (Units.Last) - Nat (Unit_Id'First);
3025       Unum      : constant Nat := Nat (U) - Nat (Unit_Id'First);
3026
3027    begin
3028       if Num_Units >= 10 and then Unum < 10 then
3029          Set_Char ('0');
3030       end if;
3031
3032       if Num_Units >= 100 and then Unum < 100 then
3033          Set_Char ('0');
3034       end if;
3035
3036       Set_Int (Unum);
3037    end Set_Unit_Number;
3038
3039    ----------------------------
3040    -- Write_Statement_Buffer --
3041    ----------------------------
3042
3043    procedure Write_Statement_Buffer is
3044    begin
3045       WBI (Statement_Buffer (1 .. Last));
3046       Last := 0;
3047    end Write_Statement_Buffer;
3048
3049    procedure Write_Statement_Buffer (S : String) is
3050    begin
3051       Set_String (S);
3052       Write_Statement_Buffer;
3053    end Write_Statement_Buffer;
3054
3055 end Bindgen;