OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [bindgen.adb] - Blame information for rev 839

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
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
               --  In the case of a body with a separate spec, where the
1054
               --  separate spec has an elaboration entity defined, this is
1055
               --  where we increment the elaboration entity.
1056
 
1057
               if U.Utype = Is_Body
1058
                 and then Units.Table (Unum_Spec).Set_Elab_Entity
1059
                 and then not CodePeer_Mode
1060
               then
1061
                  Set_String ("      E");
1062
                  Set_Unit_Number (Unum_Spec);
1063
 
1064
                  --  The AAMP target has no notion of shared libraries, and
1065
                  --  there's no possibility of reelaboration, so we treat the
1066
                  --  the elaboration var as a flag instead of a counter and
1067
                  --  simply set it.
1068
 
1069
                  if AAMP_On_Target then
1070
                     Set_String (" := 1;");
1071
 
1072
                  --  Otherwise (normal case), increment elaboration counter
1073
 
1074
                  else
1075
                     Set_String (" := E");
1076
                     Set_Unit_Number (Unum_Spec);
1077
                     Set_String (" + 1;");
1078
                  end if;
1079
 
1080
                  Write_Statement_Buffer;
1081
 
1082
               --  In the special case where the target is AAMP and the unit is
1083
               --  a spec with a body, the elaboration entity is initialized
1084
               --  here. This is done because it's the only way to accomplish
1085
               --  initialization of such entities, as there is no mechanism
1086
               --  provided for initializing global variables at load time on
1087
               --  AAMP.
1088
 
1089
               elsif AAMP_On_Target
1090
                 and then U.Utype = Is_Spec
1091
                 and then Units.Table (Unum_Spec).Set_Elab_Entity
1092
               then
1093
                  Set_String ("      E");
1094
                  Set_Unit_Number (Unum_Spec);
1095
                  Set_String (" := 0;");
1096
                  Write_Statement_Buffer;
1097
               end if;
1098
 
1099
            --  Here if elaboration code is present. If binding a library
1100
            --  or if there is a non-Ada main subprogram then we generate:
1101
 
1102
            --    if uname_E = 0 then
1103
            --       uname'elab_[spec|body];
1104
            --    end if;
1105
            --    uname_E := uname_E + 1;
1106
 
1107
            --  Otherwise, elaboration routines are called unconditionally:
1108
 
1109
            --    uname'elab_[spec|body];
1110
            --    uname_E := uname_E + 1;
1111
 
1112
            --  The uname_E increment is skipped if this is a separate spec,
1113
            --  since it will be done when we process the body.
1114
 
1115
            --  In CodePeer mode, we do not generate any reference to xxx_E
1116
            --  variables, only calls to 'Elab* subprograms.
1117
 
1118
            else
1119
               --  In the special case where the target is AAMP and the unit is
1120
               --  a spec with a body, the elaboration entity is initialized
1121
               --  here. This is done because it's the only way to accomplish
1122
               --  initialization of such entities, as there is no mechanism
1123
               --  provided for initializing global variables at load time on
1124
               --  AAMP.
1125
 
1126
               if AAMP_On_Target
1127
                 and then U.Utype = Is_Spec
1128
                 and then Units.Table (Unum_Spec).Set_Elab_Entity
1129
               then
1130
                  Set_String ("      E");
1131
                  Set_Unit_Number (Unum_Spec);
1132
                  Set_String (" := 0;");
1133
                  Write_Statement_Buffer;
1134
               end if;
1135
 
1136
               Check_Elab_Flag :=
1137
                 not CodePeer_Mode
1138
                   and then (Force_Checking_Of_Elaboration_Flags
1139
                              or Interface_Library_Unit
1140
                              or not Bind_Main_Program);
1141
 
1142
               if Check_Elab_Flag then
1143
                  Set_String ("      if E");
1144
                  Set_Unit_Number (Unum_Spec);
1145
                  Set_String (" = 0 then");
1146
                  Write_Statement_Buffer;
1147
                  Set_String ("   ");
1148
               end if;
1149
 
1150
               Set_String ("      ");
1151
               Get_Decoded_Name_String_With_Brackets (U.Uname);
1152
 
1153
               if VM_Target = CLI_Target and then U.Unit_Kind /= 's' then
1154
                  if Name_Buffer (Name_Len) = 's' then
1155
                     Name_Buffer (Name_Len - 1 .. Name_Len + 12) :=
1156
                       "_pkg'elab_spec";
1157
                  else
1158
                     Name_Buffer (Name_Len - 1 .. Name_Len + 12) :=
1159
                       "_pkg'elab_body";
1160
                  end if;
1161
 
1162
                  Name_Len := Name_Len + 12;
1163
 
1164
               else
1165
                  if Name_Buffer (Name_Len) = 's' then
1166
                     Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1167
                       "'elab_spec";
1168
                     Name_Len := Name_Len + 8;
1169
 
1170
                  --  Special case in CodePeer mode for subprogram bodies
1171
                  --  which correspond to CodePeer 'Elab_Subp_Body special
1172
                  --  init procedure.
1173
 
1174
                  elsif U.Unit_Kind = 's' and CodePeer_Mode then
1175
                     Name_Buffer (Name_Len - 1 .. Name_Len + 13) :=
1176
                       "'elab_subp_body";
1177
                     Name_Len := Name_Len + 13;
1178
 
1179
                  else
1180
                     Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1181
                       "'elab_body";
1182
                     Name_Len := Name_Len + 8;
1183
                  end if;
1184
               end if;
1185
 
1186
               Set_Casing (U.Icasing);
1187
               Set_Name_Buffer;
1188
               Set_Char (';');
1189
               Write_Statement_Buffer;
1190
 
1191
               if Check_Elab_Flag then
1192
                  WBI ("      end if;");
1193
               end if;
1194
 
1195
               if U.Utype /= Is_Spec
1196
                 and then not CodePeer_Mode
1197
               then
1198
                  Set_String ("      E");
1199
                  Set_Unit_Number (Unum_Spec);
1200
 
1201
                  --  The AAMP target has no notion of shared libraries, and
1202
                  --  there's no possibility of reelaboration, so we treat the
1203
                  --  the elaboration var as a flag instead of a counter and
1204
                  --  simply set it.
1205
 
1206
                  if AAMP_On_Target then
1207
                     Set_String (" := 1;");
1208
 
1209
                  --  Otherwise (normal case), increment elaboration counter
1210
 
1211
                  else
1212
                     Set_String (" := E");
1213
                     Set_Unit_Number (Unum_Spec);
1214
                     Set_String (" + 1;");
1215
                  end if;
1216
 
1217
                  Write_Statement_Buffer;
1218
               end if;
1219
            end if;
1220
         end;
1221
      end loop;
1222
   end Gen_Elab_Calls;
1223
 
1224
   ------------------------
1225
   -- Gen_Elab_Externals --
1226
   ------------------------
1227
 
1228
   procedure Gen_Elab_Externals is
1229
   begin
1230
      if CodePeer_Mode then
1231
         return;
1232
      end if;
1233
 
1234
      for E in Elab_Order.First .. Elab_Order.Last loop
1235
         declare
1236
            Unum : constant Unit_Id := Elab_Order.Table (E);
1237
            U    : Unit_Record renames Units.Table (Unum);
1238
 
1239
         begin
1240
            --  Check for Elab_Entity to be set for this unit
1241
 
1242
            if U.Set_Elab_Entity
1243
 
1244
              --  Don't generate reference for stand alone library
1245
 
1246
              and then not U.SAL_Interface
1247
 
1248
              --  Don't generate reference for predefined file in No_Run_Time
1249
              --  mode, since we don't include the object files in this case
1250
 
1251
              and then not
1252
                (No_Run_Time_Mode
1253
                  and then Is_Predefined_File_Name (U.Sfile))
1254
            then
1255
               Set_String ("   ");
1256
               Set_String ("E");
1257
               Set_Unit_Number (Unum);
1258
 
1259
               case VM_Target is
1260
                  when No_VM | JVM_Target =>
1261
                     Set_String (" : Short_Integer; pragma Import (Ada, ");
1262
                  when CLI_Target =>
1263
                     Set_String (" : Short_Integer; pragma Import (CIL, ");
1264
               end case;
1265
 
1266
               Set_String ("E");
1267
               Set_Unit_Number (Unum);
1268
               Set_String (", """);
1269
               Get_Name_String (U.Uname);
1270
 
1271
               --  In the case of JGNAT we need to emit an Import name that
1272
               --  includes the class name (using '$' separators in the case
1273
               --  of a child unit name).
1274
 
1275
               if VM_Target /= No_VM then
1276
                  for J in 1 .. Name_Len - 2 loop
1277
                     if VM_Target = CLI_Target
1278
                       or else Name_Buffer (J) /= '.'
1279
                     then
1280
                        Set_Char (Name_Buffer (J));
1281
                     else
1282
                        Set_String ("$");
1283
                     end if;
1284
                  end loop;
1285
 
1286
                  if VM_Target /= CLI_Target or else U.Unit_Kind = 's' then
1287
                     Set_String (".");
1288
                  else
1289
                     Set_String ("_pkg.");
1290
                  end if;
1291
 
1292
                  --  If the unit name is very long, then split the
1293
                  --  Import link name across lines using "&" (occurs
1294
                  --  in some C2 tests).
1295
 
1296
                  if 2 * Name_Len + 60 > Hostparm.Max_Line_Length then
1297
                     Set_String (""" &");
1298
                     Write_Statement_Buffer;
1299
                     Set_String ("         """);
1300
                  end if;
1301
               end if;
1302
 
1303
               Set_Unit_Name;
1304
               Set_String ("_E"");");
1305
               Write_Statement_Buffer;
1306
            end if;
1307
         end;
1308
      end loop;
1309
 
1310
      WBI ("");
1311
   end Gen_Elab_Externals;
1312
 
1313
   --------------------
1314
   -- Gen_Elab_Order --
1315
   --------------------
1316
 
1317
   procedure Gen_Elab_Order is
1318
   begin
1319
      WBI ("   --  BEGIN ELABORATION ORDER");
1320
 
1321
      for J in Elab_Order.First .. Elab_Order.Last loop
1322
         Set_String ("   --  ");
1323
         Get_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
1324
         Set_Name_Buffer;
1325
         Write_Statement_Buffer;
1326
      end loop;
1327
 
1328
      WBI ("   --  END ELABORATION ORDER");
1329
      WBI ("");
1330
   end Gen_Elab_Order;
1331
 
1332
   --------------------------
1333
   -- Gen_Finalize_Library --
1334
   --------------------------
1335
 
1336
   procedure Gen_Finalize_Library is
1337
      Count : Int := 1;
1338
      U     : Unit_Record;
1339
      Uspec : Unit_Record;
1340
      Unum  : Unit_Id;
1341
 
1342
      procedure Gen_Header;
1343
      --  Generate the header of the finalization routine
1344
 
1345
      ----------------
1346
      -- Gen_Header --
1347
      ----------------
1348
 
1349
      procedure Gen_Header is
1350
      begin
1351
         WBI ("   procedure finalize_library is");
1352
 
1353
         --  The following flag is used to check for library-level exceptions
1354
         --  raised during finalization. Symbol comes from System.Soft_Links.
1355
         --  VM targets use regular Ada to reference the entity.
1356
 
1357
         if VM_Target = No_VM then
1358
            WBI ("      LE_Set : Boolean;");
1359
 
1360
            Set_String ("      pragma Import (Ada, LE_Set, ");
1361
            Set_String ("""__gnat_library_exception_set"");");
1362
            Write_Statement_Buffer;
1363
         end if;
1364
 
1365
         WBI ("   begin");
1366
      end Gen_Header;
1367
 
1368
   --  Start of processing for Gen_Finalize_Library
1369
 
1370
   begin
1371
      if CodePeer_Mode then
1372
         return;
1373
      end if;
1374
 
1375
      for E in reverse Elab_Order.First .. Elab_Order.Last loop
1376
         Unum := Elab_Order.Table (E);
1377
         U    := Units.Table (Unum);
1378
 
1379
         --  Dealing with package bodies is a little complicated. In such
1380
         --  cases we must retrieve the package spec since it contains the
1381
         --  spec of the body finalizer.
1382
 
1383
         if U.Utype = Is_Body then
1384
            Unum  := Unum + 1;
1385
            Uspec := Units.Table (Unum);
1386
         else
1387
            Uspec := U;
1388
         end if;
1389
 
1390
         Get_Name_String (Uspec.Uname);
1391
 
1392
         --  We are only interested in non-generic packages
1393
 
1394
         if U.Unit_Kind /= 'p' or else U.Is_Generic then
1395
            null;
1396
 
1397
         --  That aren't an interface to a stand alone library
1398
 
1399
         elsif U.SAL_Interface then
1400
            null;
1401
 
1402
         --  Case of no finalization
1403
 
1404
         elsif not U.Has_Finalizer then
1405
 
1406
            --  The only case in which we have to do something is if this
1407
            --  is a body, with a separate spec, where the separate spec
1408
            --  has a finalizer. In that case, this is where we decrement
1409
            --  the elaboration entity.
1410
 
1411
            if U.Utype = Is_Body and then Uspec.Has_Finalizer then
1412
               if not Lib_Final_Built then
1413
                  Gen_Header;
1414
                  Lib_Final_Built := True;
1415
               end if;
1416
 
1417
               Set_String ("      E");
1418
               Set_Unit_Number (Unum);
1419
               Set_String (" := E");
1420
               Set_Unit_Number (Unum);
1421
               Set_String (" - 1;");
1422
               Write_Statement_Buffer;
1423
            end if;
1424
 
1425
         else
1426
            if not Lib_Final_Built then
1427
               Gen_Header;
1428
               Lib_Final_Built := True;
1429
            end if;
1430
 
1431
            --  Generate:
1432
            --    declare
1433
            --       procedure F<Count>;
1434
 
1435
            Set_String ("      declare");
1436
            Write_Statement_Buffer;
1437
 
1438
            Set_String ("         procedure F");
1439
            Set_Int    (Count);
1440
            Set_Char   (';');
1441
            Write_Statement_Buffer;
1442
 
1443
            --  Generate:
1444
            --    pragma Import (CIL, F<Count>,
1445
            --                   "xx.yy_pkg.xx__yy__finalize_[body|spec]");
1446
            --    --  for .NET targets
1447
 
1448
            --    pragma Import (Java, F<Count>,
1449
            --                   "xx$yy.xx__yy__finalize_[body|spec]");
1450
            --    --  for JVM targets
1451
 
1452
            --    pragma Import (Ada, F<Count>,
1453
            --                  "xx__yy__finalize_[body|spec]");
1454
            --    --  for default targets
1455
 
1456
            if VM_Target = CLI_Target then
1457
               Set_String ("         pragma Import (CIL, F");
1458
            elsif VM_Target = JVM_Target then
1459
               Set_String ("         pragma Import (Java, F");
1460
            else
1461
               Set_String ("         pragma Import (Ada, F");
1462
            end if;
1463
 
1464
            Set_Int (Count);
1465
            Set_String (", """);
1466
 
1467
            --  Perform name construction
1468
 
1469
            --  .NET   xx.yy_pkg.xx__yy__finalize
1470
 
1471
            if VM_Target = CLI_Target then
1472
               Set_Unit_Name (Mode => Dot);
1473
               Set_String ("_pkg.");
1474
 
1475
            --  JVM   xx$yy.xx__yy__finalize
1476
 
1477
            elsif VM_Target = JVM_Target then
1478
               Set_Unit_Name (Mode => Dollar_Sign);
1479
               Set_Char ('.');
1480
            end if;
1481
 
1482
            --  Default   xx__yy__finalize
1483
 
1484
            Set_Unit_Name;
1485
            Set_String ("__finalize_");
1486
 
1487
            --  Package spec processing
1488
 
1489
            if U.Utype = Is_Spec
1490
              or else U.Utype = Is_Spec_Only
1491
            then
1492
               Set_String ("spec");
1493
 
1494
            --  Package body processing
1495
 
1496
            else
1497
               Set_String ("body");
1498
            end if;
1499
 
1500
            Set_String (""");");
1501
            Write_Statement_Buffer;
1502
 
1503
            --  If binding a library or if there is a non-Ada main subprogram
1504
            --  then we generate:
1505
 
1506
            --    begin
1507
            --       uname_E := uname_E - 1;
1508
            --       if uname_E = 0 then
1509
            --          F<Count>;
1510
            --       end if;
1511
            --    end;
1512
 
1513
            --  Otherwise, finalization routines are called unconditionally:
1514
 
1515
            --    begin
1516
            --       uname_E := uname_E - 1;
1517
            --       F<Count>;
1518
            --    end;
1519
 
1520
            --  The uname_E decrement is skipped if this is a separate spec,
1521
            --  since it will be done when we process the body.
1522
 
1523
            WBI ("      begin");
1524
 
1525
            if U.Utype /= Is_Spec then
1526
               Set_String ("         E");
1527
               Set_Unit_Number (Unum);
1528
               Set_String (" := E");
1529
               Set_Unit_Number (Unum);
1530
               Set_String (" - 1;");
1531
               Write_Statement_Buffer;
1532
            end if;
1533
 
1534
            if Interface_Library_Unit or not Bind_Main_Program then
1535
               Set_String ("         if E");
1536
               Set_Unit_Number (Unum);
1537
               Set_String (" = 0 then");
1538
               Write_Statement_Buffer;
1539
               Set_String ("   ");
1540
            end if;
1541
 
1542
            Set_String ("         F");
1543
            Set_Int    (Count);
1544
            Set_Char   (';');
1545
            Write_Statement_Buffer;
1546
 
1547
            if Interface_Library_Unit or not Bind_Main_Program then
1548
               WBI ("         end if;");
1549
            end if;
1550
 
1551
            WBI ("      end;");
1552
 
1553
            Count := Count + 1;
1554
         end if;
1555
      end loop;
1556
 
1557
      if Lib_Final_Built then
1558
 
1559
         --  It is possible that the finalization of a library-level object
1560
         --  raised an exception. In that case import the actual exception
1561
         --  and the routine necessary to raise it.
1562
 
1563
         if VM_Target = No_VM then
1564
            WBI ("      if LE_Set then");
1565
            WBI ("         declare");
1566
            WBI ("            LE : Ada.Exceptions.Exception_Occurrence;");
1567
 
1568
            Set_String ("            pragma Import (Ada, LE, ");
1569
            Set_String ("""__gnat_library_exception"");");
1570
            Write_Statement_Buffer;
1571
 
1572
            Set_String ("            procedure Raise_From_Controlled_");
1573
            Set_String ("Operation (X : Ada.Exceptions.Exception_");
1574
            Set_String ("Occurrence);");
1575
            Write_Statement_Buffer;
1576
 
1577
            Set_String ("            pragma Import (Ada, Raise_From_");
1578
            Set_String ("Controlled_Operation, ");
1579
            Set_String ("""__gnat_raise_from_controlled_operation"");");
1580
            Write_Statement_Buffer;
1581
 
1582
            WBI ("         begin");
1583
            WBI ("            Raise_From_Controlled_Operation (LE);");
1584
            WBI ("         end;");
1585
 
1586
         --  VM-specific code, use regular Ada to produce the desired behavior
1587
 
1588
         else
1589
            WBI ("      if System.Soft_Links.Library_Exception_Set then");
1590
 
1591
            Set_String ("         Ada.Exceptions.Reraise_Occurrence (");
1592
            Set_String ("System.Soft_Links.Library_Exception);");
1593
            Write_Statement_Buffer;
1594
         end if;
1595
 
1596
         WBI ("      end if;");
1597
         WBI ("   end finalize_library;");
1598
         WBI ("");
1599
      end if;
1600
   end Gen_Finalize_Library;
1601
 
1602
   --------------
1603
   -- Gen_Main --
1604
   --------------
1605
 
1606
   procedure Gen_Main is
1607
   begin
1608
      if not No_Main_Subprogram then
1609
 
1610
         --  To call the main program, we declare it using a pragma Import
1611
         --  Ada with the right link name.
1612
 
1613
         --  It might seem more obvious to "with" the main program, and call
1614
         --  it in the normal Ada manner. We do not do this for three
1615
         --  reasons:
1616
 
1617
         --    1. It is more efficient not to recompile the main program
1618
         --    2. We are not entitled to assume the source is accessible
1619
         --    3. We don't know what options to use to compile it
1620
 
1621
         --  It is really reason 3 that is most critical (indeed we used
1622
         --  to generate the "with", but several regression tests failed).
1623
 
1624
         if ALIs.Table (ALIs.First).Main_Program = Func then
1625
            WBI ("   function Ada_Main_Program return Integer;");
1626
         else
1627
            WBI ("   procedure Ada_Main_Program;");
1628
         end if;
1629
 
1630
         Set_String ("   pragma Import (Ada, Ada_Main_Program, """);
1631
         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1632
         Set_Main_Program_Name;
1633
         Set_String (""");");
1634
 
1635
         Write_Statement_Buffer;
1636
         WBI ("");
1637
 
1638
         --  For CodePeer, declare a wrapper for the user-defined main program
1639
 
1640
         if CodePeer_Mode then
1641
            Gen_CodePeer_Wrapper;
1642
         end if;
1643
      end if;
1644
 
1645
      if Exit_Status_Supported_On_Target then
1646
         Set_String ("   function ");
1647
      else
1648
         Set_String ("   procedure ");
1649
      end if;
1650
 
1651
      Set_String (Get_Main_Name);
1652
 
1653
      if Command_Line_Args_On_Target then
1654
         Write_Statement_Buffer;
1655
         WBI ("     (argc : Integer;");
1656
         WBI ("      argv : System.Address;");
1657
         WBI ("      envp : System.Address)");
1658
 
1659
         if Exit_Status_Supported_On_Target then
1660
            WBI ("      return Integer");
1661
         end if;
1662
 
1663
         WBI ("   is");
1664
 
1665
      else
1666
         if Exit_Status_Supported_On_Target then
1667
            Set_String (" return Integer is");
1668
         else
1669
            Set_String (" is");
1670
         end if;
1671
 
1672
         Write_Statement_Buffer;
1673
      end if;
1674
 
1675
      if Opt.Default_Exit_Status /= 0
1676
        and then Bind_Main_Program
1677
        and then not Configurable_Run_Time_Mode
1678
      then
1679
         WBI ("      procedure Set_Exit_Status (Status : Integer);");
1680
         WBI ("      pragma Import (C, Set_Exit_Status, " &
1681
                     """__gnat_set_exit_status"");");
1682
         WBI ("");
1683
      end if;
1684
 
1685
      --  Initialize and Finalize
1686
 
1687
      if not CodePeer_Mode
1688
        and then not Cumulative_Restrictions.Set (No_Finalization)
1689
      then
1690
         WBI ("      procedure Initialize (Addr : System.Address);");
1691
         WBI ("      pragma Import (C, Initialize, ""__gnat_initialize"");");
1692
         WBI ("");
1693
         WBI ("      procedure Finalize;");
1694
         WBI ("      pragma Import (C, Finalize, ""__gnat_finalize"");");
1695
      end if;
1696
 
1697
      --  If we want to analyze the stack, we must import corresponding symbols
1698
 
1699
      if Dynamic_Stack_Measurement then
1700
         WBI ("");
1701
         WBI ("      procedure Output_Results;");
1702
         WBI ("      pragma Import (C, Output_Results, " &
1703
              """__gnat_stack_usage_output_results"");");
1704
 
1705
         WBI ("");
1706
         WBI ("      " &
1707
              "procedure Initialize_Stack_Analysis (Buffer_Size : Natural);");
1708
         WBI ("      pragma Import (C, Initialize_Stack_Analysis, " &
1709
              """__gnat_stack_usage_initialize"");");
1710
      end if;
1711
 
1712
      --  Deal with declarations for main program case
1713
 
1714
      if not No_Main_Subprogram then
1715
         if ALIs.Table (ALIs.First).Main_Program = Func then
1716
            WBI ("      Result : Integer;");
1717
            WBI ("");
1718
         end if;
1719
 
1720
         if Bind_Main_Program
1721
           and not Suppress_Standard_Library_On_Target
1722
           and not CodePeer_Mode
1723
         then
1724
            WBI ("      SEH : aliased array (1 .. 2) of Integer;");
1725
            WBI ("");
1726
         end if;
1727
      end if;
1728
 
1729
      --  Generate a reference to Ada_Main_Program_Name. This symbol is
1730
      --  not referenced elsewhere in the generated program, but is needed
1731
      --  by the debugger (that's why it is generated in the first place).
1732
      --  The reference stops Ada_Main_Program_Name from being optimized
1733
      --  away by smart linkers, such as the AiX linker.
1734
 
1735
      --  Because this variable is unused, we make this variable "aliased"
1736
      --  with a pragma Volatile in order to tell the compiler to preserve
1737
      --  this variable at any level of optimization.
1738
 
1739
      if Bind_Main_Program and not CodePeer_Mode then
1740
         WBI ("      Ensure_Reference : aliased System.Address := " &
1741
              "Ada_Main_Program_Name'Address;");
1742
         WBI ("      pragma Volatile (Ensure_Reference);");
1743
         WBI ("");
1744
      end if;
1745
 
1746
      WBI ("   begin");
1747
 
1748
      --  Acquire command line arguments if present on target
1749
 
1750
      if CodePeer_Mode then
1751
         null;
1752
 
1753
      elsif Command_Line_Args_On_Target then
1754
         WBI ("      gnat_argc := argc;");
1755
         WBI ("      gnat_argv := argv;");
1756
         WBI ("      gnat_envp := envp;");
1757
         WBI ("");
1758
 
1759
      --  If configurable run time and no command line args, then nothing
1760
      --  needs to be done since the gnat_argc/argv/envp variables are
1761
      --  suppressed in this case.
1762
 
1763
      elsif Configurable_Run_Time_On_Target then
1764
         null;
1765
 
1766
      --  Otherwise set dummy values (to be filled in by some other unit?)
1767
 
1768
      else
1769
         WBI ("      gnat_argc := 0;");
1770
         WBI ("      gnat_argv := System.Null_Address;");
1771
         WBI ("      gnat_envp := System.Null_Address;");
1772
      end if;
1773
 
1774
      if Opt.Default_Exit_Status /= 0
1775
        and then Bind_Main_Program
1776
        and then not Configurable_Run_Time_Mode
1777
      then
1778
         Set_String ("      Set_Exit_Status (");
1779
         Set_Int (Opt.Default_Exit_Status);
1780
         Set_String (");");
1781
         Write_Statement_Buffer;
1782
      end if;
1783
 
1784
      if Dynamic_Stack_Measurement then
1785
         Set_String ("      Initialize_Stack_Analysis (");
1786
         Set_Int (Dynamic_Stack_Measurement_Array_Size);
1787
         Set_String (");");
1788
         Write_Statement_Buffer;
1789
      end if;
1790
 
1791
      if not Cumulative_Restrictions.Set (No_Finalization)
1792
        and then not CodePeer_Mode
1793
      then
1794
         if not No_Main_Subprogram
1795
           and then Bind_Main_Program
1796
           and then not Suppress_Standard_Library_On_Target
1797
         then
1798
            WBI ("      Initialize (SEH'Address);");
1799
         else
1800
            WBI ("      Initialize (System.Null_Address);");
1801
         end if;
1802
      end if;
1803
 
1804
      WBI ("      " & Ada_Init_Name.all & ";");
1805
 
1806
      if not No_Main_Subprogram then
1807
         if CodePeer_Mode then
1808
            if ALIs.Table (ALIs.First).Main_Program = Proc then
1809
               WBI ("      " & CodePeer_Wrapper_Name & ";");
1810
            else
1811
               WBI ("      Result := " & CodePeer_Wrapper_Name & ";");
1812
            end if;
1813
 
1814
         elsif ALIs.Table (ALIs.First).Main_Program = Proc then
1815
            WBI ("      Ada_Main_Program;");
1816
 
1817
         else
1818
            WBI ("      Result := Ada_Main_Program;");
1819
         end if;
1820
      end if;
1821
 
1822
      --  Adafinal call is skipped if no finalization
1823
 
1824
      if not Cumulative_Restrictions.Set (No_Finalization) then
1825
         WBI ("      adafinal;");
1826
      end if;
1827
 
1828
      --  Prints the result of static stack analysis
1829
 
1830
      if Dynamic_Stack_Measurement then
1831
         WBI ("      Output_Results;");
1832
      end if;
1833
 
1834
      --  Finalize is only called if we have a run time
1835
 
1836
      if not Cumulative_Restrictions.Set (No_Finalization)
1837
        and then not CodePeer_Mode
1838
      then
1839
         WBI ("      Finalize;");
1840
      end if;
1841
 
1842
      --  Return result
1843
 
1844
      if Exit_Status_Supported_On_Target then
1845
         if No_Main_Subprogram
1846
           or else ALIs.Table (ALIs.First).Main_Program = Proc
1847
         then
1848
            WBI ("      return (gnat_exit_status);");
1849
         else
1850
            WBI ("      return (Result);");
1851
         end if;
1852
      end if;
1853
 
1854
      WBI ("   end;");
1855
      WBI ("");
1856
   end Gen_Main;
1857
 
1858
   ------------------------------
1859
   -- Gen_Object_Files_Options --
1860
   ------------------------------
1861
 
1862
   procedure Gen_Object_Files_Options is
1863
      Lgnat : Natural;
1864
      --  This keeps track of the position in the sorted set of entries
1865
      --  in the Linker_Options table of where the first entry from an
1866
      --  internal file appears.
1867
 
1868
      Linker_Option_List_Started : Boolean := False;
1869
      --  Set to True when "LINKER OPTION LIST" is displayed
1870
 
1871
      procedure Write_Linker_Option;
1872
      --  Write binder info linker option
1873
 
1874
      -------------------------
1875
      -- Write_Linker_Option --
1876
      -------------------------
1877
 
1878
      procedure Write_Linker_Option is
1879
         Start : Natural;
1880
         Stop  : Natural;
1881
 
1882
      begin
1883
         --  Loop through string, breaking at null's
1884
 
1885
         Start := 1;
1886
         while Start < Name_Len loop
1887
 
1888
            --  Find null ending this section
1889
 
1890
            Stop := Start + 1;
1891
            while Name_Buffer (Stop) /= ASCII.NUL
1892
              and then Stop <= Name_Len loop
1893
               Stop := Stop + 1;
1894
            end loop;
1895
 
1896
            --  Process section if non-null
1897
 
1898
            if Stop > Start then
1899
               if Output_Linker_Option_List then
1900
                  if not Zero_Formatting then
1901
                     if not Linker_Option_List_Started then
1902
                        Linker_Option_List_Started := True;
1903
                        Write_Eol;
1904
                        Write_Str ("     LINKER OPTION LIST");
1905
                        Write_Eol;
1906
                        Write_Eol;
1907
                     end if;
1908
 
1909
                     Write_Str ("   ");
1910
                  end if;
1911
 
1912
                  Write_Str (Name_Buffer (Start .. Stop - 1));
1913
                  Write_Eol;
1914
               end if;
1915
               WBI ("   --   " & Name_Buffer (Start .. Stop - 1));
1916
            end if;
1917
 
1918
            Start := Stop + 1;
1919
         end loop;
1920
      end Write_Linker_Option;
1921
 
1922
   --  Start of processing for Gen_Object_Files_Options
1923
 
1924
   begin
1925
      WBI ("--  BEGIN Object file/option list");
1926
 
1927
      if Object_List_Filename /= null then
1928
         Set_List_File (Object_List_Filename.all);
1929
      end if;
1930
 
1931
      for E in Elab_Order.First .. Elab_Order.Last loop
1932
 
1933
         --  If not spec that has an associated body, then generate a comment
1934
         --  giving the name of the corresponding object file.
1935
 
1936
         if not Units.Table (Elab_Order.Table (E)).SAL_Interface
1937
           and then Units.Table (Elab_Order.Table (E)).Utype /= Is_Spec
1938
         then
1939
            Get_Name_String
1940
              (ALIs.Table
1941
                (Units.Table (Elab_Order.Table (E)).My_ALI).Ofile_Full_Name);
1942
 
1943
            --  If the presence of an object file is necessary or if it exists,
1944
            --  then use it.
1945
 
1946
            if not Hostparm.Exclude_Missing_Objects
1947
              or else
1948
                System.OS_Lib.Is_Regular_File (Name_Buffer (1 .. Name_Len))
1949
            then
1950
               WBI ("   --   " & Name_Buffer (1 .. Name_Len));
1951
 
1952
               if Output_Object_List then
1953
                  Write_Str (Name_Buffer (1 .. Name_Len));
1954
                  Write_Eol;
1955
               end if;
1956
            end if;
1957
         end if;
1958
      end loop;
1959
 
1960
      if Object_List_Filename /= null then
1961
         Close_List_File;
1962
      end if;
1963
 
1964
      --  Add a "-Ldir" for each directory in the object path
1965
      if VM_Target /= CLI_Target then
1966
         for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
1967
            declare
1968
               Dir : constant String_Ptr := Dir_In_Obj_Search_Path (J);
1969
            begin
1970
               Name_Len := 0;
1971
               Add_Str_To_Name_Buffer ("-L");
1972
               Add_Str_To_Name_Buffer (Dir.all);
1973
               Write_Linker_Option;
1974
            end;
1975
         end loop;
1976
      end if;
1977
 
1978
      --  Sort linker options
1979
 
1980
      --  This sort accomplishes two important purposes:
1981
 
1982
      --    a) All application files are sorted to the front, and all GNAT
1983
      --       internal files are sorted to the end. This results in a well
1984
      --       defined dividing line between the two sets of files, for the
1985
      --       purpose of inserting certain standard library references into
1986
      --       the linker arguments list.
1987
 
1988
      --    b) Given two different units, we sort the linker options so that
1989
      --       those from a unit earlier in the elaboration order comes later
1990
      --       in the list. This is a heuristic designed to create a more
1991
      --       friendly order of linker options when the operations appear in
1992
      --       separate units. The idea is that if unit A must be elaborated
1993
      --       before unit B, then it is more likely that B references
1994
      --       libraries included by A, than vice versa, so we want libraries
1995
      --       included by A to come after libraries included by B.
1996
 
1997
      --  These two criteria are implemented by function Lt_Linker_Option. Note
1998
      --  that a special case of b) is that specs are elaborated before bodies,
1999
      --  so linker options from specs come after linker options for bodies,
2000
      --  and again, the assumption is that libraries used by the body are more
2001
      --  likely to reference libraries used by the spec, than vice versa.
2002
 
2003
      Sort
2004
        (Linker_Options.Last,
2005
         Move_Linker_Option'Access,
2006
         Lt_Linker_Option'Access);
2007
 
2008
      --  Write user linker options, i.e. the set of linker options that come
2009
      --  from all files other than GNAT internal files, Lgnat is left set to
2010
      --  point to the first entry from a GNAT internal file, or past the end
2011
      --  of the entries if there are no internal files.
2012
 
2013
      Lgnat := Linker_Options.Last + 1;
2014
 
2015
      for J in 1 .. Linker_Options.Last loop
2016
         if not Linker_Options.Table (J).Internal_File then
2017
            Get_Name_String (Linker_Options.Table (J).Name);
2018
            Write_Linker_Option;
2019
         else
2020
            Lgnat := J;
2021
            exit;
2022
         end if;
2023
      end loop;
2024
 
2025
      --  Now we insert standard linker options that must appear after the
2026
      --  entries from user files, and before the entries from GNAT run-time
2027
      --  files. The reason for this decision is that libraries referenced
2028
      --  by internal routines may reference these standard library entries.
2029
 
2030
      --  Note that we do not insert anything when pragma No_Run_Time has been
2031
      --  specified or when the standard libraries are not to be used,
2032
      --  otherwise on some platforms, such as VMS, we may get duplicate
2033
      --  symbols when linking.
2034
 
2035
      if not (Opt.No_Run_Time_Mode or else Opt.No_Stdlib) then
2036
         Name_Len := 0;
2037
 
2038
         if Opt.Shared_Libgnat then
2039
            Add_Str_To_Name_Buffer ("-shared");
2040
         else
2041
            Add_Str_To_Name_Buffer ("-static");
2042
         end if;
2043
 
2044
         --  Write directly to avoid -K output (why???)
2045
 
2046
         WBI ("   --   " & Name_Buffer (1 .. Name_Len));
2047
 
2048
         if With_DECGNAT then
2049
            Name_Len := 0;
2050
 
2051
            if Opt.Shared_Libgnat then
2052
               Add_Str_To_Name_Buffer (Shared_Lib ("decgnat"));
2053
            else
2054
               Add_Str_To_Name_Buffer ("-ldecgnat");
2055
            end if;
2056
 
2057
            Write_Linker_Option;
2058
         end if;
2059
 
2060
         if With_GNARL then
2061
            Name_Len := 0;
2062
 
2063
            if Opt.Shared_Libgnat then
2064
               Add_Str_To_Name_Buffer (Shared_Lib ("gnarl"));
2065
            else
2066
               Add_Str_To_Name_Buffer ("-lgnarl");
2067
            end if;
2068
 
2069
            Write_Linker_Option;
2070
         end if;
2071
 
2072
         Name_Len := 0;
2073
 
2074
         if Opt.Shared_Libgnat then
2075
            Add_Str_To_Name_Buffer (Shared_Lib ("gnat"));
2076
         else
2077
            Add_Str_To_Name_Buffer ("-lgnat");
2078
         end if;
2079
 
2080
         Write_Linker_Option;
2081
      end if;
2082
 
2083
      --  Write linker options from all internal files
2084
 
2085
      for J in Lgnat .. Linker_Options.Last loop
2086
         Get_Name_String (Linker_Options.Table (J).Name);
2087
         Write_Linker_Option;
2088
      end loop;
2089
 
2090
      if Output_Linker_Option_List and then not Zero_Formatting then
2091
         Write_Eol;
2092
      end if;
2093
 
2094
      WBI ("--  END Object file/option list   ");
2095
   end Gen_Object_Files_Options;
2096
 
2097
   ---------------------
2098
   -- Gen_Output_File --
2099
   ---------------------
2100
 
2101
   procedure Gen_Output_File (Filename : String) is
2102
   begin
2103
      --  Acquire settings for Interrupt_State pragmas
2104
 
2105
      Set_IS_Pragma_Table;
2106
 
2107
      --  Acquire settings for Priority_Specific_Dispatching pragma
2108
 
2109
      Set_PSD_Pragma_Table;
2110
 
2111
      --  For JGNAT the main program is already generated by the compiler
2112
 
2113
      if VM_Target = JVM_Target then
2114
         Bind_Main_Program := False;
2115
      end if;
2116
 
2117
      --  Override time slice value if -T switch is set
2118
 
2119
      if Time_Slice_Set then
2120
         ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value;
2121
      end if;
2122
 
2123
      --  Count number of elaboration calls
2124
 
2125
      for E in Elab_Order.First .. Elab_Order.Last loop
2126
         if Units.Table (Elab_Order.Table (E)).No_Elab then
2127
            null;
2128
         else
2129
            Num_Elab_Calls := Num_Elab_Calls + 1;
2130
         end if;
2131
      end loop;
2132
 
2133
      --  Generate output file in appropriate language
2134
 
2135
      Check_System_Restrictions_Used;
2136
      Check_Dispatching_Domains_Used;
2137
 
2138
      Gen_Output_File_Ada (Filename);
2139
   end Gen_Output_File;
2140
 
2141
   -------------------------
2142
   -- Gen_Output_File_Ada --
2143
   -------------------------
2144
 
2145
   procedure Gen_Output_File_Ada (Filename : String) is
2146
 
2147
      Ada_Main : constant String := Get_Ada_Main_Name;
2148
      --  Name to be used for generated Ada main program. See the body of
2149
      --  function Get_Ada_Main_Name for details on the form of the name.
2150
 
2151
      Needs_Library_Finalization : constant Boolean :=
2152
                                     not Configurable_Run_Time_On_Target
2153
                                       and then Has_Finalizer;
2154
      --  For restricted run-time libraries (ZFP and Ravenscar) tasks are
2155
      --  non-terminating, so we do not want finalization.
2156
 
2157
      Bfiles : Name_Id;
2158
      --  Name of generated bind file (spec)
2159
 
2160
      Bfileb : Name_Id;
2161
      --  Name of generated bind file (body)
2162
 
2163
   begin
2164
      --  Create spec first
2165
 
2166
      Create_Binder_Output (Filename, 's', Bfiles);
2167
 
2168
      --  We always compile the binder file in Ada 95 mode so that we properly
2169
      --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2170
      --  of the Ada 2005 or Ada 2012 constructs are needed by the binder file.
2171
 
2172
      WBI ("pragma Ada_95;");
2173
 
2174
      --  If we are operating in Restrictions (No_Exception_Handlers) mode,
2175
      --  then we need to make sure that the binder program is compiled with
2176
      --  the same restriction, so that no exception tables are generated.
2177
 
2178
      if Cumulative_Restrictions.Set (No_Exception_Handlers) then
2179
         WBI ("pragma Restrictions (No_Exception_Handlers);");
2180
      end if;
2181
 
2182
      --  Same processing for Restrictions (No_Exception_Propagation)
2183
 
2184
      if Cumulative_Restrictions.Set (No_Exception_Propagation) then
2185
         WBI ("pragma Restrictions (No_Exception_Propagation);");
2186
      end if;
2187
 
2188
      --  Same processing for pragma No_Run_Time
2189
 
2190
      if No_Run_Time_Mode then
2191
         WBI ("pragma No_Run_Time;");
2192
      end if;
2193
 
2194
      --  Generate with of System so we can reference System.Address
2195
 
2196
      WBI ("with System;");
2197
 
2198
      --  Generate with of System.Initialize_Scalars if active
2199
 
2200
      if Initialize_Scalars_Used then
2201
         WBI ("with System.Scalar_Values;");
2202
      end if;
2203
 
2204
      --  Generate with of System.Secondary_Stack if active
2205
 
2206
      if Sec_Stack_Used and then Default_Sec_Stack_Size /= -1 then
2207
         WBI ("with System.Secondary_Stack;");
2208
      end if;
2209
 
2210
      Resolve_Binder_Options;
2211
 
2212
      --  Usually, adafinal is called using a pragma Import C. Since Import C
2213
      --  doesn't have the same semantics for VMs or CodePeer use standard Ada.
2214
 
2215
      if not Suppress_Standard_Library_On_Target then
2216
         if CodePeer_Mode then
2217
            WBI ("with System.Standard_Library;");
2218
         elsif VM_Target /= No_VM then
2219
            WBI ("with System.Soft_Links;");
2220
            WBI ("with System.Standard_Library;");
2221
         end if;
2222
      end if;
2223
 
2224
      WBI ("package " & Ada_Main & " is");
2225
      WBI ("   pragma Warnings (Off);");
2226
 
2227
      --  Main program case
2228
 
2229
      if Bind_Main_Program then
2230
         if VM_Target = No_VM then
2231
 
2232
            --  Generate argc/argv stuff unless suppressed
2233
 
2234
            if Command_Line_Args_On_Target
2235
              or not Configurable_Run_Time_On_Target
2236
            then
2237
               WBI ("");
2238
               WBI ("   gnat_argc : Integer;");
2239
               WBI ("   gnat_argv : System.Address;");
2240
               WBI ("   gnat_envp : System.Address;");
2241
 
2242
               --  If the standard library is not suppressed, these variables
2243
               --  are in the run-time data area for easy run time access.
2244
 
2245
               if not Suppress_Standard_Library_On_Target then
2246
                  WBI ("");
2247
                  WBI ("   pragma Import (C, gnat_argc);");
2248
                  WBI ("   pragma Import (C, gnat_argv);");
2249
                  WBI ("   pragma Import (C, gnat_envp);");
2250
               end if;
2251
            end if;
2252
 
2253
            --  Define exit status. Again in normal mode, this is in the
2254
            --  run-time library, and is initialized there, but in the
2255
            --  configurable runtime case, the variable is declared and
2256
            --  initialized in this file.
2257
 
2258
            WBI ("");
2259
 
2260
            if Configurable_Run_Time_Mode then
2261
               if Exit_Status_Supported_On_Target then
2262
                  WBI ("   gnat_exit_status : Integer := 0;");
2263
               end if;
2264
 
2265
            else
2266
               WBI ("   gnat_exit_status : Integer;");
2267
               WBI ("   pragma Import (C, gnat_exit_status);");
2268
            end if;
2269
         end if;
2270
 
2271
         --  Generate the GNAT_Version and Ada_Main_Program_Name info only for
2272
         --  the main program. Otherwise, it can lead under some circumstances
2273
         --  to a symbol duplication during the link (for instance when a C
2274
         --  program uses two Ada libraries). Also zero terminate the string
2275
         --  so that its end can be found reliably at run time.
2276
 
2277
         WBI ("");
2278
         WBI ("   GNAT_Version : constant String :=");
2279
         WBI ("                    """ & Ver_Prefix &
2280
                                   Gnat_Version_String &
2281
                                   """ & ASCII.NUL;");
2282
         WBI ("   pragma Export (C, GNAT_Version, ""__gnat_version"");");
2283
 
2284
         WBI ("");
2285
         Set_String ("   Ada_Main_Program_Name : constant String := """);
2286
         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2287
 
2288
         if VM_Target = No_VM then
2289
            Set_Main_Program_Name;
2290
            Set_String (""" & ASCII.NUL;");
2291
         else
2292
            Set_String (Name_Buffer (1 .. Name_Len - 2) & """;");
2293
         end if;
2294
 
2295
         Write_Statement_Buffer;
2296
 
2297
         WBI
2298
           ("   pragma Export (C, Ada_Main_Program_Name, " &
2299
            """__gnat_ada_main_program_name"");");
2300
      end if;
2301
 
2302
      WBI ("");
2303
      WBI ("   procedure " & Ada_Init_Name.all & ";");
2304
      WBI ("   pragma Export (C, " & Ada_Init_Name.all & ", """ &
2305
           Ada_Init_Name.all & """);");
2306
 
2307
      --  If -a has been specified use pragma Linker_Constructor for the init
2308
      --  procedure and pragma Linker_Destructor for the final procedure.
2309
 
2310
      if Use_Pragma_Linker_Constructor then
2311
         WBI ("   pragma Linker_Constructor (" & Ada_Init_Name.all & ");");
2312
      end if;
2313
 
2314
      if not Cumulative_Restrictions.Set (No_Finalization) then
2315
         WBI ("");
2316
         WBI ("   procedure " & Ada_Final_Name.all & ";");
2317
         WBI ("   pragma Export (C, " & Ada_Final_Name.all & ", """ &
2318
              Ada_Final_Name.all & """);");
2319
 
2320
         if Use_Pragma_Linker_Constructor then
2321
            WBI ("   pragma Linker_Destructor (" & Ada_Final_Name.all & ");");
2322
         end if;
2323
      end if;
2324
 
2325
      if Bind_Main_Program and then VM_Target = No_VM then
2326
 
2327
         WBI ("");
2328
 
2329
         if Exit_Status_Supported_On_Target then
2330
            Set_String ("   function ");
2331
         else
2332
            Set_String ("   procedure ");
2333
         end if;
2334
 
2335
         Set_String (Get_Main_Name);
2336
 
2337
         --  Generate argument list if present
2338
 
2339
         if Command_Line_Args_On_Target then
2340
            Write_Statement_Buffer;
2341
            WBI ("     (argc : Integer;");
2342
            WBI ("      argv : System.Address;");
2343
            Set_String
2344
                ("      envp : System.Address)");
2345
 
2346
            if Exit_Status_Supported_On_Target then
2347
               Write_Statement_Buffer;
2348
               WBI ("      return Integer;");
2349
            else
2350
               Write_Statement_Buffer (";");
2351
            end if;
2352
 
2353
         else
2354
            if Exit_Status_Supported_On_Target then
2355
               Write_Statement_Buffer (" return Integer;");
2356
            else
2357
               Write_Statement_Buffer (";");
2358
            end if;
2359
         end if;
2360
 
2361
         WBI ("   pragma Export (C, " & Get_Main_Name & ", """ &
2362
           Get_Main_Name & """);");
2363
      end if;
2364
 
2365
      Gen_Versions;
2366
      Gen_Elab_Order;
2367
 
2368
      --  Spec is complete
2369
 
2370
      WBI ("");
2371
      WBI ("end " & Ada_Main & ";");
2372
      Close_Binder_Output;
2373
 
2374
      --  Prepare to write body
2375
 
2376
      Create_Binder_Output (Filename, 'b', Bfileb);
2377
 
2378
      --  We always compile the binder file in Ada 95 mode so that we properly
2379
      --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2380
      --  of the Ada 2005/2012 constructs are needed by the binder file.
2381
 
2382
      WBI ("pragma Ada_95;");
2383
 
2384
      --  Output Source_File_Name pragmas which look like
2385
 
2386
      --    pragma Source_File_Name (Ada_Main, Spec_File_Name => "sss");
2387
      --    pragma Source_File_Name (Ada_Main, Body_File_Name => "bbb");
2388
 
2389
      --  where sss/bbb are the spec/body file names respectively
2390
 
2391
      Get_Name_String (Bfiles);
2392
      Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2393
 
2394
      WBI ("pragma Source_File_Name (" &
2395
           Ada_Main &
2396
           ", Spec_File_Name => """ &
2397
           Name_Buffer (1 .. Name_Len + 3));
2398
 
2399
      Get_Name_String (Bfileb);
2400
      Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2401
 
2402
      WBI ("pragma Source_File_Name (" &
2403
           Ada_Main &
2404
           ", Body_File_Name => """ &
2405
           Name_Buffer (1 .. Name_Len + 3));
2406
 
2407
      --  Generate with of System.Restrictions to initialize
2408
      --  Run_Time_Restrictions.
2409
 
2410
      if System_Restrictions_Used
2411
        and not Suppress_Standard_Library_On_Target
2412
      then
2413
         WBI ("");
2414
         WBI ("with System.Restrictions;");
2415
      end if;
2416
 
2417
      if Needs_Library_Finalization then
2418
         WBI ("with Ada.Exceptions;");
2419
      end if;
2420
 
2421
      WBI ("");
2422
      WBI ("package body " & Ada_Main & " is");
2423
      WBI ("   pragma Warnings (Off);");
2424
      WBI ("");
2425
 
2426
      --  Generate externals for elaboration entities
2427
 
2428
      Gen_Elab_Externals;
2429
 
2430
      if not CodePeer_Mode then
2431
         if not Suppress_Standard_Library_On_Target then
2432
 
2433
            --  Generate Priority_Specific_Dispatching pragma string
2434
 
2435
            Set_String
2436
              ("   Local_Priority_Specific_Dispatching : " &
2437
               "constant String := """);
2438
 
2439
            for J in 0 .. PSD_Pragma_Settings.Last loop
2440
               Set_Char (PSD_Pragma_Settings.Table (J));
2441
            end loop;
2442
 
2443
            Set_String (""";");
2444
            Write_Statement_Buffer;
2445
 
2446
            --  Generate Interrupt_State pragma string
2447
 
2448
            Set_String ("   Local_Interrupt_States : constant String := """);
2449
 
2450
            for J in 0 .. IS_Pragma_Settings.Last loop
2451
               Set_Char (IS_Pragma_Settings.Table (J));
2452
            end loop;
2453
 
2454
            Set_String (""";");
2455
            Write_Statement_Buffer;
2456
            WBI ("");
2457
         end if;
2458
 
2459
         --  The B.1 (39) implementation advice says that the adainit/adafinal
2460
         --  routines should be idempotent. Generate a flag to ensure that.
2461
 
2462
         WBI ("   Is_Elaborated : Boolean := False;");
2463
         WBI ("");
2464
      end if;
2465
 
2466
      --  Generate the adafinal routine unless there is no finalization to do
2467
 
2468
      if not Cumulative_Restrictions.Set (No_Finalization) then
2469
         if Needs_Library_Finalization then
2470
            Gen_Finalize_Library;
2471
         end if;
2472
 
2473
         Gen_Adafinal;
2474
      end if;
2475
 
2476
      Gen_Adainit;
2477
 
2478
      if Bind_Main_Program and then VM_Target = No_VM then
2479
         Gen_Main;
2480
      end if;
2481
 
2482
      --  Output object file list and the Ada body is complete
2483
 
2484
      Gen_Object_Files_Options;
2485
 
2486
      WBI ("");
2487
      WBI ("end " & Ada_Main & ";");
2488
 
2489
      Close_Binder_Output;
2490
   end Gen_Output_File_Ada;
2491
 
2492
   ----------------------
2493
   -- Gen_Restrictions --
2494
   ----------------------
2495
 
2496
   procedure Gen_Restrictions is
2497
      Count : Integer;
2498
 
2499
   begin
2500
      if Suppress_Standard_Library_On_Target
2501
        or not System_Restrictions_Used
2502
      then
2503
         return;
2504
      end if;
2505
 
2506
      WBI ("      System.Restrictions.Run_Time_Restrictions :=");
2507
      WBI ("        (Set =>");
2508
      Set_String      ("          (");
2509
 
2510
      Count := 0;
2511
 
2512
      for J in Cumulative_Restrictions.Set'Range loop
2513
         Set_Boolean (Cumulative_Restrictions.Set (J));
2514
         Set_String (", ");
2515
         Count := Count + 1;
2516
 
2517
         if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2518
            Write_Statement_Buffer;
2519
            Set_String ("           ");
2520
            Count := 0;
2521
         end if;
2522
      end loop;
2523
 
2524
      Set_String_Replace ("),");
2525
      Write_Statement_Buffer;
2526
      Set_String ("         Value => (");
2527
 
2528
      for J in Cumulative_Restrictions.Value'Range loop
2529
         Set_Int (Int (Cumulative_Restrictions.Value (J)));
2530
         Set_String (", ");
2531
      end loop;
2532
 
2533
      Set_String_Replace ("),");
2534
      Write_Statement_Buffer;
2535
      WBI ("         Violated =>");
2536
      Set_String ("          (");
2537
      Count := 0;
2538
 
2539
      for J in Cumulative_Restrictions.Violated'Range loop
2540
         Set_Boolean (Cumulative_Restrictions.Violated (J));
2541
         Set_String (", ");
2542
         Count := Count + 1;
2543
 
2544
         if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2545
            Write_Statement_Buffer;
2546
            Set_String ("           ");
2547
            Count := 0;
2548
         end if;
2549
      end loop;
2550
 
2551
      Set_String_Replace ("),");
2552
      Write_Statement_Buffer;
2553
      Set_String ("         Count => (");
2554
 
2555
      for J in Cumulative_Restrictions.Count'Range loop
2556
         Set_Int (Int (Cumulative_Restrictions.Count (J)));
2557
         Set_String (", ");
2558
      end loop;
2559
 
2560
      Set_String_Replace ("),");
2561
      Write_Statement_Buffer;
2562
      Set_String ("         Unknown => (");
2563
 
2564
      for J in Cumulative_Restrictions.Unknown'Range loop
2565
         Set_Boolean (Cumulative_Restrictions.Unknown (J));
2566
         Set_String (", ");
2567
      end loop;
2568
 
2569
      Set_String_Replace ("))");
2570
      Set_String (";");
2571
      Write_Statement_Buffer;
2572
   end Gen_Restrictions;
2573
 
2574
   ------------------
2575
   -- Gen_Versions --
2576
   ------------------
2577
 
2578
   --  This routine generates lines such as:
2579
 
2580
   --    unnnnn : constant Integer := 16#hhhhhhhh#;
2581
   --    pragma Export (C, unnnnn, unam);
2582
 
2583
   --  for each unit, where unam is the unit name suffixed by either B or S for
2584
   --  body or spec, with dots replaced by double underscores, and hhhhhhhh is
2585
   --  the version number, and nnnnn is a 5-digits serial number.
2586
 
2587
   procedure Gen_Versions is
2588
      Ubuf : String (1 .. 6) := "u00000";
2589
 
2590
      procedure Increment_Ubuf;
2591
      --  Little procedure to increment the serial number
2592
 
2593
      --------------------
2594
      -- Increment_Ubuf --
2595
      --------------------
2596
 
2597
      procedure Increment_Ubuf is
2598
      begin
2599
         for J in reverse Ubuf'Range loop
2600
            Ubuf (J) := Character'Succ (Ubuf (J));
2601
            exit when Ubuf (J) <= '9';
2602
            Ubuf (J) := '0';
2603
         end loop;
2604
      end Increment_Ubuf;
2605
 
2606
   --  Start of processing for Gen_Versions
2607
 
2608
   begin
2609
      WBI ("");
2610
 
2611
      WBI ("   type Version_32 is mod 2 ** 32;");
2612
      for U in Units.First .. Units.Last loop
2613
         if not Units.Table (U).SAL_Interface
2614
           and then
2615
             (not Bind_For_Library or else Units.Table (U).Directly_Scanned)
2616
         then
2617
            Increment_Ubuf;
2618
            WBI ("   " & Ubuf & " : constant Version_32 := 16#" &
2619
                 Units.Table (U).Version & "#;");
2620
            Set_String ("   pragma Export (C, ");
2621
            Set_String (Ubuf);
2622
            Set_String (", """);
2623
 
2624
            Get_Name_String (Units.Table (U).Uname);
2625
 
2626
            for K in 1 .. Name_Len loop
2627
               if Name_Buffer (K) = '.' then
2628
                  Set_Char ('_');
2629
                  Set_Char ('_');
2630
 
2631
               elsif Name_Buffer (K) = '%' then
2632
                  exit;
2633
 
2634
               else
2635
                  Set_Char (Name_Buffer (K));
2636
               end if;
2637
            end loop;
2638
 
2639
            if Name_Buffer (Name_Len) = 's' then
2640
               Set_Char ('S');
2641
            else
2642
               Set_Char ('B');
2643
            end if;
2644
 
2645
            Set_String (""");");
2646
            Write_Statement_Buffer;
2647
         end if;
2648
      end loop;
2649
   end Gen_Versions;
2650
 
2651
   ------------------------
2652
   -- Get_Main_Unit_Name --
2653
   ------------------------
2654
 
2655
   function Get_Main_Unit_Name (S : String) return String is
2656
      Result : String := S;
2657
 
2658
   begin
2659
      for J in S'Range loop
2660
         if Result (J) = '.' then
2661
            Result (J) := '_';
2662
         end if;
2663
      end loop;
2664
 
2665
      return Result;
2666
   end Get_Main_Unit_Name;
2667
 
2668
   -----------------------
2669
   -- Get_Ada_Main_Name --
2670
   -----------------------
2671
 
2672
   function Get_Ada_Main_Name return String is
2673
      Suffix : constant String := "_00";
2674
      Name   : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
2675
                 Opt.Ada_Main_Name.all & Suffix;
2676
      Nlen   : Natural;
2677
 
2678
   begin
2679
      --  The main program generated by JGNAT expects a package called
2680
      --  ada_<main procedure>.
2681
      if VM_Target /= No_VM then
2682
         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2683
         return "ada_" & Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
2684
      end if;
2685
 
2686
      --  For CodePeer, we want reproducible names (independent of other
2687
      --  mains that may or may not be present) that don't collide
2688
      --  when analyzing multiple mains and which are easily recognizable
2689
      --  as "ada_main" names.
2690
      if CodePeer_Mode then
2691
         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2692
         return "ada_main_for_" &
2693
           Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
2694
      end if;
2695
 
2696
      --  This loop tries the following possibilities in order
2697
      --    <Ada_Main>
2698
      --    <Ada_Main>_01
2699
      --    <Ada_Main>_02
2700
      --    ..
2701
      --    <Ada_Main>_99
2702
      --  where <Ada_Main> is equal to Opt.Ada_Main_Name. By default,
2703
      --  it is set to 'ada_main'.
2704
 
2705
      for J in 0 .. 99 loop
2706
         if J = 0 then
2707
            Nlen := Name'Length - Suffix'Length;
2708
         else
2709
            Nlen := Name'Length;
2710
            Name (Name'Last) := Character'Val (J mod 10 + Character'Pos ('0'));
2711
            Name (Name'Last - 1) :=
2712
              Character'Val (J /   10 + Character'Pos ('0'));
2713
         end if;
2714
 
2715
         for K in ALIs.First .. ALIs.Last loop
2716
            for L in ALIs.Table (K).First_Unit .. ALIs.Table (K).Last_Unit loop
2717
 
2718
               --  Get unit name, removing %b or %e at end
2719
 
2720
               Get_Name_String (Units.Table (L).Uname);
2721
               Name_Len := Name_Len - 2;
2722
 
2723
               if Name_Buffer (1 .. Name_Len) = Name (1 .. Nlen) then
2724
                  goto Continue;
2725
               end if;
2726
            end loop;
2727
         end loop;
2728
 
2729
         return Name (1 .. Nlen);
2730
 
2731
      <<Continue>>
2732
         null;
2733
      end loop;
2734
 
2735
      --  If we fall through, just use a peculiar unlikely name
2736
 
2737
      return ("Qwertyuiop");
2738
   end Get_Ada_Main_Name;
2739
 
2740
   -------------------
2741
   -- Get_Main_Name --
2742
   -------------------
2743
 
2744
   function Get_Main_Name return String is
2745
   begin
2746
      --  Explicit name given with -M switch
2747
 
2748
      if Bind_Alternate_Main_Name then
2749
         return Alternate_Main_Name.all;
2750
 
2751
      --  Case of main program name to be used directly
2752
 
2753
      elsif Use_Ada_Main_Program_Name_On_Target then
2754
 
2755
         --  Get main program name
2756
 
2757
         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2758
 
2759
         --  If this is a child name, return only the name of the child, since
2760
         --  we can't have dots in a nested program name. Note that we do not
2761
         --  include the %b at the end of the unit name.
2762
 
2763
         for J in reverse 1 .. Name_Len - 2 loop
2764
            if J = 1 or else Name_Buffer (J - 1) = '.' then
2765
               return Name_Buffer (J .. Name_Len - 2);
2766
            end if;
2767
         end loop;
2768
 
2769
         raise Program_Error; -- impossible exit
2770
 
2771
      --  Case where "main" is to be used as default
2772
 
2773
      else
2774
         return "main";
2775
      end if;
2776
   end Get_Main_Name;
2777
 
2778
   ---------------------
2779
   -- Get_WC_Encoding --
2780
   ---------------------
2781
 
2782
   function Get_WC_Encoding return Character is
2783
   begin
2784
      --  If encoding method specified by -W switch, then return it
2785
 
2786
      if Wide_Character_Encoding_Method_Specified then
2787
         return WC_Encoding_Letters (Wide_Character_Encoding_Method);
2788
 
2789
      --  If no main program, and not specified, set brackets, we really have
2790
      --  no better choice. If some other encoding is required when there is
2791
      --  no main, it must be set explicitly using -Wx.
2792
 
2793
      --  Note: if the ALI file always passed the wide character encoding of
2794
      --  every file, then we could use the encoding of the initial specified
2795
      --  file, but this information is passed only for potential main
2796
      --  programs. We could fix this sometime, but it is a very minor point
2797
      --  (wide character default encoding for [Wide_[Wide_]Text_IO when there
2798
      --  is no main program).
2799
 
2800
      elsif No_Main_Subprogram then
2801
         return 'b';
2802
 
2803
      --  Otherwise if there is a main program, take encoding from it
2804
 
2805
      else
2806
         return ALIs.Table (ALIs.First).WC_Encoding;
2807
      end if;
2808
   end Get_WC_Encoding;
2809
 
2810
   -------------------
2811
   -- Has_Finalizer --
2812
   -------------------
2813
 
2814
   function Has_Finalizer return Boolean is
2815
      U     : Unit_Record;
2816
      Unum  : Unit_Id;
2817
 
2818
   begin
2819
      for E in reverse Elab_Order.First .. Elab_Order.Last loop
2820
         Unum := Elab_Order.Table (E);
2821
         U    := Units.Table (Unum);
2822
 
2823
         --  We are only interested in non-generic packages
2824
 
2825
         if U.Unit_Kind = 'p'
2826
           and then U.Has_Finalizer
2827
           and then not U.Is_Generic
2828
           and then not U.No_Elab
2829
         then
2830
            return True;
2831
         end if;
2832
      end loop;
2833
 
2834
      return False;
2835
   end Has_Finalizer;
2836
 
2837
   ----------------------
2838
   -- Lt_Linker_Option --
2839
   ----------------------
2840
 
2841
   function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean is
2842
   begin
2843
      --  Sort internal files last
2844
 
2845
      if Linker_Options.Table (Op1).Internal_File
2846
           /=
2847
         Linker_Options.Table (Op2).Internal_File
2848
      then
2849
         --  Note: following test uses False < True
2850
 
2851
         return Linker_Options.Table (Op1).Internal_File
2852
                  <
2853
                Linker_Options.Table (Op2).Internal_File;
2854
 
2855
      --  If both internal or both non-internal, sort according to the
2856
      --  elaboration position. A unit that is elaborated later should come
2857
      --  earlier in the linker options list.
2858
 
2859
      else
2860
         return Units.Table (Linker_Options.Table (Op1).Unit).Elab_Position
2861
                  >
2862
                Units.Table (Linker_Options.Table (Op2).Unit).Elab_Position;
2863
 
2864
      end if;
2865
   end Lt_Linker_Option;
2866
 
2867
   ------------------------
2868
   -- Move_Linker_Option --
2869
   ------------------------
2870
 
2871
   procedure Move_Linker_Option (From : Natural; To : Natural) is
2872
   begin
2873
      Linker_Options.Table (To) := Linker_Options.Table (From);
2874
   end Move_Linker_Option;
2875
 
2876
   ----------------------------
2877
   -- Resolve_Binder_Options --
2878
   ----------------------------
2879
 
2880
   procedure Resolve_Binder_Options is
2881
   begin
2882
      for E in Elab_Order.First .. Elab_Order.Last loop
2883
         Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
2884
 
2885
         --  This is not a perfect approach, but is the current protocol
2886
         --  between the run-time and the binder to indicate that tasking is
2887
         --  used: system.os_interface should always be used by any tasking
2888
         --  application.
2889
 
2890
         if Name_Buffer (1 .. 19) = "system.os_interface" then
2891
            With_GNARL := True;
2892
         end if;
2893
 
2894
         --  Ditto for declib and the "dec" package
2895
 
2896
         if OpenVMS_On_Target and then Name_Buffer (1 .. 5) = "dec%s" then
2897
            With_DECGNAT := True;
2898
         end if;
2899
      end loop;
2900
   end Resolve_Binder_Options;
2901
 
2902
   -----------------
2903
   -- Set_Boolean --
2904
   -----------------
2905
 
2906
   procedure Set_Boolean (B : Boolean) is
2907
      True_Str  : constant String := "True";
2908
      False_Str : constant String := "False";
2909
   begin
2910
      if B then
2911
         Statement_Buffer (Last + 1 .. Last + True_Str'Length) := True_Str;
2912
         Last := Last + True_Str'Length;
2913
      else
2914
         Statement_Buffer (Last + 1 .. Last + False_Str'Length) := False_Str;
2915
         Last := Last + False_Str'Length;
2916
      end if;
2917
   end Set_Boolean;
2918
 
2919
   --------------
2920
   -- Set_Char --
2921
   --------------
2922
 
2923
   procedure Set_Char (C : Character) is
2924
   begin
2925
      Last := Last + 1;
2926
      Statement_Buffer (Last) := C;
2927
   end Set_Char;
2928
 
2929
   -------------
2930
   -- Set_Int --
2931
   -------------
2932
 
2933
   procedure Set_Int (N : Int) is
2934
   begin
2935
      if N < 0 then
2936
         Set_String ("-");
2937
         Set_Int (-N);
2938
 
2939
      else
2940
         if N > 9 then
2941
            Set_Int (N / 10);
2942
         end if;
2943
 
2944
         Last := Last + 1;
2945
         Statement_Buffer (Last) :=
2946
           Character'Val (N mod 10 + Character'Pos ('0'));
2947
      end if;
2948
   end Set_Int;
2949
 
2950
   -------------------------
2951
   -- Set_IS_Pragma_Table --
2952
   -------------------------
2953
 
2954
   procedure Set_IS_Pragma_Table is
2955
   begin
2956
      for F in ALIs.First .. ALIs.Last loop
2957
         for K in ALIs.Table (F).First_Interrupt_State ..
2958
                  ALIs.Table (F).Last_Interrupt_State
2959
         loop
2960
            declare
2961
               Inum : constant Int :=
2962
                        Interrupt_States.Table (K).Interrupt_Id;
2963
               Stat : constant Character :=
2964
                        Interrupt_States.Table (K).Interrupt_State;
2965
 
2966
            begin
2967
               while IS_Pragma_Settings.Last < Inum loop
2968
                  IS_Pragma_Settings.Append ('n');
2969
               end loop;
2970
 
2971
               IS_Pragma_Settings.Table (Inum) := Stat;
2972
            end;
2973
         end loop;
2974
      end loop;
2975
   end Set_IS_Pragma_Table;
2976
 
2977
   ---------------------------
2978
   -- Set_Main_Program_Name --
2979
   ---------------------------
2980
 
2981
   procedure Set_Main_Program_Name is
2982
   begin
2983
      --  Note that name has %b on the end which we ignore
2984
 
2985
      --  First we output the initial _ada_ since we know that the main
2986
      --  program is a library level subprogram.
2987
 
2988
      Set_String ("_ada_");
2989
 
2990
      --  Copy name, changing dots to double underscores
2991
 
2992
      for J in 1 .. Name_Len - 2 loop
2993
         if Name_Buffer (J) = '.' then
2994
            Set_String ("__");
2995
         else
2996
            Set_Char (Name_Buffer (J));
2997
         end if;
2998
      end loop;
2999
   end Set_Main_Program_Name;
3000
 
3001
   ---------------------
3002
   -- Set_Name_Buffer --
3003
   ---------------------
3004
 
3005
   procedure Set_Name_Buffer is
3006
   begin
3007
      for J in 1 .. Name_Len loop
3008
         Set_Char (Name_Buffer (J));
3009
      end loop;
3010
   end Set_Name_Buffer;
3011
 
3012
   -------------------------
3013
   -- Set_PSD_Pragma_Table --
3014
   -------------------------
3015
 
3016
   procedure Set_PSD_Pragma_Table is
3017
   begin
3018
      for F in ALIs.First .. ALIs.Last loop
3019
         for K in ALIs.Table (F).First_Specific_Dispatching ..
3020
                  ALIs.Table (F).Last_Specific_Dispatching
3021
         loop
3022
            declare
3023
               DTK : Specific_Dispatching_Record
3024
                       renames Specific_Dispatching.Table (K);
3025
 
3026
            begin
3027
               while PSD_Pragma_Settings.Last < DTK.Last_Priority loop
3028
                  PSD_Pragma_Settings.Append ('F');
3029
               end loop;
3030
 
3031
               for Prio in DTK.First_Priority .. DTK.Last_Priority loop
3032
                  PSD_Pragma_Settings.Table (Prio) := DTK.Dispatching_Policy;
3033
               end loop;
3034
            end;
3035
         end loop;
3036
      end loop;
3037
   end Set_PSD_Pragma_Table;
3038
 
3039
   ----------------
3040
   -- Set_String --
3041
   ----------------
3042
 
3043
   procedure Set_String (S : String) is
3044
   begin
3045
      Statement_Buffer (Last + 1 .. Last + S'Length) := S;
3046
      Last := Last + S'Length;
3047
   end Set_String;
3048
 
3049
   ------------------------
3050
   -- Set_String_Replace --
3051
   ------------------------
3052
 
3053
   procedure Set_String_Replace (S : String) is
3054
   begin
3055
      Statement_Buffer (Last - S'Length + 1 .. Last) := S;
3056
   end Set_String_Replace;
3057
 
3058
   -------------------
3059
   -- Set_Unit_Name --
3060
   -------------------
3061
 
3062
   procedure Set_Unit_Name (Mode : Qualification_Mode := Double_Underscores) is
3063
   begin
3064
      for J in 1 .. Name_Len - 2 loop
3065
         if Name_Buffer (J) = '.' then
3066
            if Mode = Double_Underscores then
3067
               Set_String ("__");
3068
            elsif Mode = Dot then
3069
               Set_Char ('.');
3070
            else
3071
               Set_Char ('$');
3072
            end if;
3073
         else
3074
            Set_Char (Name_Buffer (J));
3075
         end if;
3076
      end loop;
3077
   end Set_Unit_Name;
3078
 
3079
   ---------------------
3080
   -- Set_Unit_Number --
3081
   ---------------------
3082
 
3083
   procedure Set_Unit_Number (U : Unit_Id) is
3084
      Num_Units : constant Nat := Nat (Units.Last) - Nat (Unit_Id'First);
3085
      Unum      : constant Nat := Nat (U) - Nat (Unit_Id'First);
3086
 
3087
   begin
3088
      if Num_Units >= 10 and then Unum < 10 then
3089
         Set_Char ('0');
3090
      end if;
3091
 
3092
      if Num_Units >= 100 and then Unum < 100 then
3093
         Set_Char ('0');
3094
      end if;
3095
 
3096
      Set_Int (Unum);
3097
   end Set_Unit_Number;
3098
 
3099
   ----------------------------
3100
   -- Write_Statement_Buffer --
3101
   ----------------------------
3102
 
3103
   procedure Write_Statement_Buffer is
3104
   begin
3105
      WBI (Statement_Buffer (1 .. Last));
3106
      Last := 0;
3107
   end Write_Statement_Buffer;
3108
 
3109
   procedure Write_Statement_Buffer (S : String) is
3110
   begin
3111
      Set_String (S);
3112
      Write_Statement_Buffer;
3113
   end Write_Statement_Buffer;
3114
 
3115
end Bindgen;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.