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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ada/] [bindgen.adb] - Blame information for rev 307

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

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

powered by: WebSVN 2.1.0

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