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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [lib-writ.adb] - Blame information for rev 20

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

Line No. Rev Author Line
1 12 jlechner
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                             L I B . W R I T                              --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2005, 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 2,  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 COPYING.  If not, write --
19
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20
-- Boston, MA 02110-1301, USA.                                              --
21
--                                                                          --
22
-- GNAT was originally developed  by the GNAT team at  New York University. --
23
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
24
--                                                                          --
25
------------------------------------------------------------------------------
26
 
27
with ALI;      use ALI;
28
with Atree;    use Atree;
29
with Casing;   use Casing;
30
with Einfo;    use Einfo;
31
with Errout;   use Errout;
32
with Fname;    use Fname;
33
with Fname.UF; use Fname.UF;
34
with Lib.Util; use Lib.Util;
35
with Lib.Xref; use Lib.Xref;
36
with Namet;    use Namet;
37
with Nlists;   use Nlists;
38
with Gnatvsn;  use Gnatvsn;
39
with Opt;      use Opt;
40
with Osint;    use Osint;
41
with Osint.C;  use Osint.C;
42
with Par;
43
with Restrict; use Restrict;
44
with Rident;   use Rident;
45
with Scn;      use Scn;
46
with Sinfo;    use Sinfo;
47
with Sinput;   use Sinput;
48
with Stringt;  use Stringt;
49
with Tbuild;   use Tbuild;
50
with Uname;    use Uname;
51
 
52
with System.Case_Util; use System.Case_Util;
53
with System.WCh_Con;   use System.WCh_Con;
54
 
55
package body Lib.Writ is
56
 
57
   -----------------------
58
   -- Local Subprograms --
59
   -----------------------
60
 
61
   procedure Write_Unit_Name (N : Node_Id);
62
   --  Used to write out the unit name for R (pragma Restriction) lines
63
   --  for uses of Restriction (No_Dependence => unit-name).
64
 
65
   ----------------------------------
66
   -- Add_Preprocessing_Dependency --
67
   ----------------------------------
68
 
69
   procedure Add_Preprocessing_Dependency (S : Source_File_Index) is
70
   begin
71
      Units.Increment_Last;
72
      Units.Table (Units.Last) :=
73
        (Unit_File_Name  => File_Name (S),
74
         Unit_Name       => No_Name,
75
         Expected_Unit   => No_Name,
76
         Source_Index    => S,
77
         Cunit           => Empty,
78
         Cunit_Entity    => Empty,
79
         Dependency_Num  => 0,
80
         Dynamic_Elab    => False,
81
         Fatal_Error     => False,
82
         Generate_Code   => False,
83
         Has_RACW        => False,
84
         Ident_String    => Empty,
85
         Loading         => False,
86
         Main_Priority   => -1,
87
         Munit_Index     => 0,
88
         Serial_Number   => 0,
89
         Version         => 0,
90
         Error_Location  => No_Location);
91
   end Add_Preprocessing_Dependency;
92
 
93
   ------------------------------
94
   -- Ensure_System_Dependency --
95
   ------------------------------
96
 
97
   procedure Ensure_System_Dependency is
98
      System_Uname : Unit_Name_Type;
99
      --  Unit name for system spec if needed for dummy entry
100
 
101
      System_Fname : File_Name_Type;
102
      --  File name for system spec if needed for dummy entry
103
 
104
   begin
105
      --  Nothing to do if we already compiled System
106
 
107
      for Unum in Units.First .. Last_Unit loop
108
         if Units.Table (Unum).Source_Index = System_Source_File_Index then
109
            return;
110
         end if;
111
      end loop;
112
 
113
      --  If no entry for system.ads in the units table, then add a entry
114
      --  to the units table for system.ads, which will be referenced when
115
      --  the ali file is generated. We need this because every unit depends
116
      --  on system as a result of Targparm scanning the system.ads file to
117
      --  determine the target dependent parameters for the compilation.
118
 
119
      Name_Len := 6;
120
      Name_Buffer (1 .. 6) := "system";
121
      System_Uname := Name_To_Unit_Name (Name_Enter);
122
      System_Fname := File_Name (System_Source_File_Index);
123
 
124
      Units.Increment_Last;
125
      Units.Table (Units.Last) := (
126
        Unit_File_Name  => System_Fname,
127
        Unit_Name       => System_Uname,
128
        Expected_Unit   => System_Uname,
129
        Source_Index    => System_Source_File_Index,
130
        Cunit           => Empty,
131
        Cunit_Entity    => Empty,
132
        Dependency_Num  => 0,
133
        Dynamic_Elab    => False,
134
        Fatal_Error     => False,
135
        Generate_Code   => False,
136
        Has_RACW        => False,
137
        Ident_String    => Empty,
138
        Loading         => False,
139
        Main_Priority   => -1,
140
        Munit_Index     => 0,
141
        Serial_Number   => 0,
142
        Version         => 0,
143
        Error_Location  => No_Location);
144
 
145
      --  Parse system.ads so that the checksum is set right
146
      --  Style checks are not applied.
147
 
148
      declare
149
         Save_Mindex : constant Nat := Multiple_Unit_Index;
150
         Save_Style  : constant Boolean := Style_Check;
151
      begin
152
         Multiple_Unit_Index := 0;
153
         Style_Check := False;
154
         Initialize_Scanner (Units.Last, System_Source_File_Index);
155
         Discard_List (Par (Configuration_Pragmas => False));
156
         Style_Check := Save_Style;
157
         Multiple_Unit_Index := Save_Mindex;
158
      end;
159
   end Ensure_System_Dependency;
160
 
161
   ---------------
162
   -- Write_ALI --
163
   ---------------
164
 
165
   procedure Write_ALI (Object : Boolean) is
166
 
167
      ----------------
168
      -- Local Data --
169
      ----------------
170
 
171
      Last_Unit : constant Unit_Number_Type := Units.Last;
172
      --  Record unit number of last unit. We capture this in case we
173
      --  have to add a dummy entry to the unit table for package System.
174
 
175
      With_Flags : array (Units.First .. Last_Unit) of Boolean;
176
      --  Array of flags to show which units are with'ed
177
 
178
      Elab_Flags : array (Units.First .. Last_Unit) of Boolean;
179
      --  Array of flags to show which units have pragma Elaborate set
180
 
181
      Elab_All_Flags : array (Units.First .. Last_Unit) of Boolean;
182
      --  Array of flags to show which units have pragma Elaborate All set
183
 
184
      Elab_Des_Flags : array (Units.First .. Last_Unit) of Boolean;
185
      --  Array of flags to show which units have Elaborate_Desirable set
186
 
187
      Elab_All_Des_Flags : array (Units.First .. Last_Unit) of Boolean;
188
      --  Array of flags to show which units have Elaborate_All_Desirable set
189
 
190
      Sdep_Table : Unit_Ref_Table (1 .. Pos (Last_Unit - Units.First + 2));
191
      --  Sorted table of source dependencies. One extra entry in case we
192
      --  have to add a dummy entry for System.
193
 
194
      Num_Sdep : Nat := 0;
195
      --  Number of active entries in Sdep_Table
196
 
197
      -----------------------
198
      -- Local Subprograms --
199
      -----------------------
200
 
201
      procedure Collect_Withs (Cunit : Node_Id);
202
      --  Collect with lines for entries in the context clause of the
203
      --  given compilation unit, Cunit.
204
 
205
      procedure Update_Tables_From_ALI_File;
206
      --  Given an up to date ALI file (see Up_To_Date_ALI_file_Exists
207
      --  function), update tables from the ALI information, including
208
      --  specifically the Compilation_Switches table.
209
 
210
      function Up_To_Date_ALI_File_Exists return Boolean;
211
      --  If there exists an ALI file that is up to date, then this function
212
      --  initializes the tables in the ALI spec to contain information on
213
      --  this file (using Scan_ALI) and returns True. If no file exists,
214
      --  or the file is not up to date, then False is returned.
215
 
216
      procedure Write_Unit_Information (Unit_Num : Unit_Number_Type);
217
      --  Write out the library information for one unit for which code is
218
      --  generated (includes unit line and with lines).
219
 
220
      procedure Write_With_Lines;
221
      --  Write out with lines collected by calls to Collect_Withs
222
 
223
      -------------------
224
      -- Collect_Withs --
225
      -------------------
226
 
227
      procedure Collect_Withs (Cunit : Node_Id) is
228
         Item : Node_Id;
229
         Unum : Unit_Number_Type;
230
 
231
      begin
232
         Item := First (Context_Items (Cunit));
233
         while Present (Item) loop
234
 
235
            --  Process with clause
236
 
237
            --  Ada 2005 (AI-50217): limited with_clauses do not create
238
            --  dependencies
239
 
240
            if Nkind (Item) = N_With_Clause
241
              and then not (Limited_Present (Item))
242
            then
243
               Unum := Get_Cunit_Unit_Number (Library_Unit (Item));
244
               With_Flags (Unum) := True;
245
 
246
               if Elaborate_Present (Item) then
247
                  Elab_Flags (Unum) := True;
248
               end if;
249
 
250
               if Elaborate_All_Present (Item) then
251
                  Elab_All_Flags (Unum) := True;
252
               end if;
253
 
254
               if Elaborate_All_Desirable (Item) then
255
                  Elab_All_Des_Flags (Unum) := True;
256
               end if;
257
 
258
               if Elaborate_Desirable (Item) then
259
                  Elab_Des_Flags (Unum) := True;
260
               end if;
261
            end if;
262
 
263
            Next (Item);
264
         end loop;
265
      end Collect_Withs;
266
 
267
      --------------------------------
268
      -- Up_To_Date_ALI_File_Exists --
269
      --------------------------------
270
 
271
      function Up_To_Date_ALI_File_Exists return Boolean is
272
         Name : File_Name_Type;
273
         Text : Text_Buffer_Ptr;
274
         Id   : Sdep_Id;
275
         Sind : Source_File_Index;
276
 
277
      begin
278
         Opt.Check_Object_Consistency := True;
279
         Read_Library_Info (Name, Text);
280
 
281
         --  Return if we could not find an ALI file
282
 
283
         if Text = null then
284
            return False;
285
         end if;
286
 
287
         --  Return if ALI file has bad format
288
 
289
         Initialize_ALI;
290
 
291
         if Scan_ALI (Name, Text, False, Err => True) = No_ALI_Id then
292
            return False;
293
         end if;
294
 
295
         --  If we have an OK ALI file, check if it is up to date
296
         --  Note that we assume that the ALI read has all the entries
297
         --  we have in our table, plus some additional ones (that can
298
         --  come from expansion).
299
 
300
         Id := First_Sdep_Entry;
301
         for J in 1 .. Num_Sdep loop
302
            Sind := Units.Table (Sdep_Table (J)).Source_Index;
303
 
304
            while Sdep.Table (Id).Sfile /= File_Name (Sind) loop
305
               if Id = Sdep.Last then
306
                  return False;
307
               else
308
                  Id := Id + 1;
309
               end if;
310
            end loop;
311
 
312
            if Sdep.Table (Id).Stamp /= Time_Stamp (Sind) then
313
               return False;
314
            end if;
315
         end loop;
316
 
317
         return True;
318
      end Up_To_Date_ALI_File_Exists;
319
 
320
      ---------------------------------
321
      -- Update_Tables_From_ALI_File --
322
      ---------------------------------
323
 
324
      procedure Update_Tables_From_ALI_File is
325
      begin
326
         --  Build Compilation_Switches table
327
 
328
         Compilation_Switches.Init;
329
 
330
         for J in First_Arg_Entry .. Args.Last loop
331
            Compilation_Switches.Increment_Last;
332
            Compilation_Switches.Table (Compilation_Switches.Last) :=
333
              Args.Table (J);
334
         end loop;
335
      end Update_Tables_From_ALI_File;
336
 
337
      ----------------------------
338
      -- Write_Unit_Information --
339
      ----------------------------
340
 
341
      procedure Write_Unit_Information (Unit_Num : Unit_Number_Type) is
342
         Unode : constant Node_Id   := Cunit (Unit_Num);
343
         Ukind : constant Node_Kind := Nkind (Unit (Unode));
344
         Uent  : constant Entity_Id := Cunit_Entity (Unit_Num);
345
         Pnode : Node_Id;
346
 
347
      begin
348
         Write_Info_Initiate ('U');
349
         Write_Info_Char (' ');
350
         Write_Info_Name (Unit_Name (Unit_Num));
351
         Write_Info_Tab (25);
352
         Write_Info_Name (Unit_File_Name (Unit_Num));
353
 
354
         Write_Info_Tab (49);
355
         Write_Info_Str (Version_Get (Unit_Num));
356
 
357
         if (Is_Subprogram (Uent)
358
              or else Ekind (Uent) = E_Package
359
              or else Is_Generic_Unit (Uent))
360
           and then Body_Needed_For_SAL (Uent)
361
         then
362
            Write_Info_Str (" BN");
363
         end if;
364
 
365
         if Dynamic_Elab (Unit_Num) then
366
            Write_Info_Str (" DE");
367
         end if;
368
 
369
         --  We set the Elaborate_Body indication if either an explicit pragma
370
         --  was present, or if this is an instantiation. RM 12.3(20) requires
371
         --  that the body be immediately elaborated after the spec. We would
372
         --  normally do that anyway, but the EB we generate here ensures that
373
         --  this gets done even when we use the -p gnatbind switch.
374
 
375
         if Has_Pragma_Elaborate_Body (Uent)
376
           or else (Ukind = N_Package_Declaration
377
                     and then Is_Generic_Instance (Uent)
378
                     and then Present (Corresponding_Body (Unit (Unode))))
379
         then
380
            Write_Info_Str (" EB");
381
         end if;
382
 
383
         --  Now see if we should tell the binder that an elaboration entity
384
         --  is present, which must be reset to true during elaboration. We
385
         --  generate the indication if the following condition is met:
386
 
387
         --  If this is a spec ...
388
 
389
         if (Is_Subprogram (Uent)
390
               or else
391
             Ekind (Uent) = E_Package
392
               or else
393
             Is_Generic_Unit (Uent))
394
 
395
            --  and an elaboration entity was declared ...
396
 
397
            and then Present (Elaboration_Entity (Uent))
398
 
399
            --  and either the elaboration flag is required ...
400
 
401
            and then
402
              (Elaboration_Entity_Required (Uent)
403
 
404
               --  or this unit has elaboration code ...
405
 
406
               or else not Has_No_Elaboration_Code (Unode)
407
 
408
               --  or this unit has a separate body and this
409
               --  body has elaboration code.
410
 
411
               or else
412
                 (Ekind (Uent) = E_Package
413
                   and then Present (Body_Entity (Uent))
414
                   and then
415
                     not Has_No_Elaboration_Code
416
                           (Parent
417
                             (Declaration_Node
418
                               (Body_Entity (Uent))))))
419
         then
420
            Write_Info_Str (" EE");
421
         end if;
422
 
423
         if Has_No_Elaboration_Code (Unode) then
424
            Write_Info_Str (" NE");
425
         end if;
426
 
427
         if Is_Preelaborated (Uent) then
428
            Write_Info_Str (" PR");
429
         end if;
430
 
431
         if Is_Pure (Uent) then
432
            Write_Info_Str (" PU");
433
         end if;
434
 
435
         if Has_RACW (Unit_Num) then
436
            Write_Info_Str (" RA");
437
         end if;
438
 
439
         if Is_Remote_Call_Interface (Uent) then
440
            Write_Info_Str (" RC");
441
         end if;
442
 
443
         if Is_Remote_Types (Uent) then
444
            Write_Info_Str (" RT");
445
         end if;
446
 
447
         if Is_Shared_Passive (Uent) then
448
            Write_Info_Str (" SP");
449
         end if;
450
 
451
         if Ukind = N_Subprogram_Declaration
452
           or else Ukind = N_Subprogram_Body
453
         then
454
            Write_Info_Str (" SU");
455
 
456
         elsif Ukind = N_Package_Declaration
457
                 or else
458
               Ukind = N_Package_Body
459
         then
460
            --  If this is a wrapper package for a subprogram instantiation,
461
            --  the user view is the subprogram. Note that in this case the
462
            --  ali file contains both the spec and body of the instance.
463
 
464
            if Is_Wrapper_Package (Uent) then
465
               Write_Info_Str (" SU");
466
            else
467
               Write_Info_Str (" PK");
468
            end if;
469
 
470
         elsif Ukind = N_Generic_Package_Declaration then
471
            Write_Info_Str (" PK");
472
 
473
         end if;
474
 
475
         if Ukind in N_Generic_Declaration
476
           or else
477
             (Present (Library_Unit (Unode))
478
                and then
479
              Nkind (Unit (Library_Unit (Unode))) in N_Generic_Declaration)
480
         then
481
            Write_Info_Str (" GE");
482
         end if;
483
 
484
         if not Is_Internal_File_Name (Unit_File_Name (Unit_Num), True) then
485
            case Identifier_Casing (Source_Index (Unit_Num)) is
486
               when All_Lower_Case => Write_Info_Str (" IL");
487
               when All_Upper_Case => Write_Info_Str (" IU");
488
               when others         => null;
489
            end case;
490
 
491
            case Keyword_Casing (Source_Index (Unit_Num)) is
492
               when Mixed_Case     => Write_Info_Str (" KM");
493
               when All_Upper_Case => Write_Info_Str (" KU");
494
               when others         => null;
495
            end case;
496
         end if;
497
 
498
         if Initialize_Scalars then
499
            Write_Info_Str (" IS");
500
         end if;
501
 
502
         Write_Info_EOL;
503
 
504
         --  Generate with lines, first those that are directly with'ed
505
 
506
         for J in With_Flags'Range loop
507
            With_Flags         (J) := False;
508
            Elab_Flags         (J) := False;
509
            Elab_All_Flags     (J) := False;
510
            Elab_Des_Flags     (J) := False;
511
            Elab_All_Des_Flags (J) := False;
512
         end loop;
513
 
514
         Collect_Withs (Unode);
515
 
516
         --  For a body, we must also check for any subunits which belong to
517
         --  it and which have context clauses of their own, since these
518
         --  with'ed units are part of its own elaboration dependencies.
519
 
520
         if Nkind (Unit (Unode)) in N_Unit_Body then
521
            for S in Units.First .. Last_Unit loop
522
 
523
               --  We are only interested in subunits.
524
               --  For preproc. data and def. files, Cunit is Empty, so
525
               --  we need to test that first.
526
 
527
               if Cunit (S) /= Empty
528
                 and then Nkind (Unit (Cunit (S))) = N_Subunit
529
               then
530
                  Pnode := Library_Unit (Cunit (S));
531
 
532
                  --  In gnatc mode, the errors in the subunits will not
533
                  --  have been recorded, but the analysis of the subunit
534
                  --  may have failed. There is no information to add to
535
                  --  ALI file in this case.
536
 
537
                  if No (Pnode) then
538
                     exit;
539
                  end if;
540
 
541
                  --  Find ultimate parent of the subunit
542
 
543
                  while Nkind (Unit (Pnode)) = N_Subunit loop
544
                     Pnode := Library_Unit (Pnode);
545
                  end loop;
546
 
547
                  --  See if it belongs to current unit, and if so, include
548
                  --  its with_clauses.
549
 
550
                  if Pnode = Unode then
551
                     Collect_Withs (Cunit (S));
552
                  end if;
553
               end if;
554
            end loop;
555
         end if;
556
 
557
         Write_With_Lines;
558
 
559
         --  Output linker option lines
560
 
561
         for J in 1 .. Linker_Option_Lines.Last loop
562
            declare
563
               S : constant Linker_Option_Entry :=
564
                     Linker_Option_Lines.Table (J);
565
               C : Character;
566
 
567
            begin
568
               if S.Unit = Unit_Num then
569
                  Write_Info_Initiate ('L');
570
                  Write_Info_Str (" """);
571
 
572
                  for J in 1 .. String_Length (S.Option) loop
573
                     C := Get_Character (Get_String_Char (S.Option, J));
574
 
575
                     if C in Character'Val (16#20#) .. Character'Val (16#7E#)
576
                       and then C /= '{'
577
                     then
578
                        Write_Info_Char (C);
579
 
580
                        if C = '"' then
581
                           Write_Info_Char (C);
582
                        end if;
583
 
584
                     else
585
                        declare
586
                           Hex : constant array (0 .. 15) of Character :=
587
                                   "0123456789ABCDEF";
588
 
589
                        begin
590
                           Write_Info_Char ('{');
591
                           Write_Info_Char (Hex (Character'Pos (C) / 16));
592
                           Write_Info_Char (Hex (Character'Pos (C) mod 16));
593
                           Write_Info_Char ('}');
594
                        end;
595
                     end if;
596
                  end loop;
597
 
598
                  Write_Info_Char ('"');
599
                  Write_Info_EOL;
600
               end if;
601
            end;
602
         end loop;
603
      end Write_Unit_Information;
604
 
605
      ----------------------
606
      -- Write_With_Lines --
607
      ----------------------
608
 
609
      procedure Write_With_Lines is
610
         With_Table : Unit_Ref_Table (1 .. Pos (Last_Unit - Units.First + 1));
611
         Num_Withs  : Int := 0;
612
         Unum       : Unit_Number_Type;
613
         Cunit      : Node_Id;
614
         Cunite     : Entity_Id;
615
         Uname      : Unit_Name_Type;
616
         Fname      : File_Name_Type;
617
         Pname      : constant Unit_Name_Type :=
618
                        Get_Parent_Spec_Name (Unit_Name (Main_Unit));
619
         Body_Fname : File_Name_Type;
620
         Body_Index : Nat;
621
 
622
      begin
623
         --  Loop to build the with table. A with on the main unit itself
624
         --  is ignored (AARM 10.2(14a)). Such a with-clause can occur if
625
         --  the main unit is a subprogram with no spec, and a subunit of
626
         --  it unecessarily withs the parent.
627
 
628
         for J in Units.First + 1 .. Last_Unit loop
629
 
630
            --  Add element to with table if it is with'ed or if it is the
631
            --  parent spec of the main unit (case of main unit is a child
632
            --  unit). The latter with is not needed for semantic purposes,
633
            --  but is required by the binder for elaboration purposes.
634
            --  For preproc. data and def. files, there is no Unit_Name,
635
            --  check for that first.
636
 
637
            if Unit_Name (J) /= No_Name
638
              and then (With_Flags (J) or else Unit_Name (J) = Pname)
639
            then
640
               Num_Withs := Num_Withs + 1;
641
               With_Table (Num_Withs) := J;
642
            end if;
643
         end loop;
644
 
645
         --  Sort and output the table
646
 
647
         Sort (With_Table (1 .. Num_Withs));
648
 
649
         for J in 1 .. Num_Withs loop
650
            Unum   := With_Table (J);
651
            Cunit  := Units.Table (Unum).Cunit;
652
            Cunite := Units.Table (Unum).Cunit_Entity;
653
            Uname  := Units.Table (Unum).Unit_Name;
654
            Fname  := Units.Table (Unum).Unit_File_Name;
655
 
656
            Write_Info_Initiate ('W');
657
            Write_Info_Char (' ');
658
            Write_Info_Name (Uname);
659
 
660
            --  Now we need to figure out the names of the files that contain
661
            --  the with'ed unit. These will usually be the files for the body,
662
            --  except in the case of a package that has no body.
663
 
664
            if (Nkind (Unit (Cunit)) not in N_Generic_Declaration
665
                  and then
666
                Nkind (Unit (Cunit)) not in N_Generic_Renaming_Declaration)
667
              or else Generic_Separately_Compiled (Cunite)
668
            then
669
               Write_Info_Tab (25);
670
 
671
               if Is_Spec_Name (Uname) then
672
                  Body_Fname :=
673
                    Get_File_Name
674
                      (Get_Body_Name (Uname),
675
                       Subunit => False, May_Fail => True);
676
 
677
                  Body_Index :=
678
                    Get_Unit_Index
679
                      (Get_Body_Name (Uname));
680
 
681
                  if Body_Fname = No_File then
682
                     Body_Fname := Get_File_Name (Uname, Subunit => False);
683
                     Body_Index := Get_Unit_Index (Uname);
684
                  end if;
685
 
686
               else
687
                  Body_Fname := Get_File_Name (Uname, Subunit => False);
688
                  Body_Index := Get_Unit_Index (Uname);
689
               end if;
690
 
691
               --  A package is considered to have a body if it requires
692
               --  a body or if a body is present in Ada 83 mode.
693
 
694
               if Body_Required (Cunit)
695
                 or else (Ada_Version = Ada_83
696
                           and then Full_Source_Name (Body_Fname) /= No_File)
697
               then
698
                  --  Ensure that on platforms where the file names are not
699
                  --  case sensitive, the recorded file name is in lower case.
700
 
701
                  if not File_Names_Case_Sensitive then
702
                     Get_Name_String (Body_Fname);
703
                     To_Lower (Name_Buffer (1 .. Name_Len));
704
                     Body_Fname := Name_Find;
705
                  end if;
706
 
707
                  Write_Info_Name (Body_Fname);
708
                  Write_Info_Tab (49);
709
                  Write_Info_Name
710
                    (Lib_File_Name (Body_Fname, Body_Index));
711
               else
712
                  --  Ensure that on platforms where the file names are not
713
                  --  case sensitive, the recorded file name is in lower case.
714
 
715
                  if not File_Names_Case_Sensitive then
716
                     Get_Name_String (Fname);
717
                     To_Lower (Name_Buffer (1 .. Name_Len));
718
                     Fname := Name_Find;
719
                  end if;
720
 
721
                  Write_Info_Name (Fname);
722
                  Write_Info_Tab (49);
723
                  Write_Info_Name
724
                    (Lib_File_Name (Fname, Munit_Index (Unum)));
725
               end if;
726
 
727
               if Elab_Flags (Unum) then
728
                  Write_Info_Str ("  E");
729
               end if;
730
 
731
               if Elab_All_Flags (Unum) then
732
                  Write_Info_Str ("  EA");
733
               end if;
734
 
735
               if Elab_Des_Flags (Unum) then
736
                  Write_Info_Str ("  ED");
737
               end if;
738
 
739
               if Elab_All_Des_Flags (Unum) then
740
                  Write_Info_Str ("  AD");
741
               end if;
742
            end if;
743
 
744
            Write_Info_EOL;
745
         end loop;
746
      end Write_With_Lines;
747
 
748
   --  Start of processing for Write_ALI
749
 
750
   begin
751
      --  We never write an ALI file if the original operating mode was
752
      --  syntax-only (-gnats switch used in compiler invocation line)
753
 
754
      if Original_Operating_Mode = Check_Syntax then
755
         return;
756
      end if;
757
 
758
      --  Build sorted source dependency table. We do this right away,
759
      --  because it is referenced by Up_To_Date_ALI_File_Exists.
760
 
761
      for Unum in Units.First .. Last_Unit loop
762
         if Cunit_Entity (Unum) = Empty
763
           or else not From_With_Type (Cunit_Entity (Unum))
764
         then
765
            Num_Sdep := Num_Sdep + 1;
766
            Sdep_Table (Num_Sdep) := Unum;
767
         end if;
768
      end loop;
769
 
770
      --  Sort the table so that the D lines are in order
771
 
772
      Lib.Sort (Sdep_Table (1 .. Num_Sdep));
773
 
774
      --  If we are not generating code, and there is an up to date
775
      --  ali file accessible, read it, and acquire the compilation
776
      --  arguments from this file.
777
 
778
      if Operating_Mode /= Generate_Code then
779
         if Up_To_Date_ALI_File_Exists then
780
            Update_Tables_From_ALI_File;
781
            return;
782
         end if;
783
      end if;
784
 
785
      --  Otherwise acquire compilation arguments and prepare to write
786
      --  out a new ali file.
787
 
788
      Create_Output_Library_Info;
789
 
790
      --  Output version line
791
 
792
      Write_Info_Initiate ('V');
793
      Write_Info_Str (" """);
794
      Write_Info_Str (Verbose_Library_Version);
795
      Write_Info_Char ('"');
796
 
797
      Write_Info_EOL;
798
 
799
      --  Output main program line if this is acceptable main program
800
 
801
      Output_Main_Program_Line : declare
802
         U : Node_Id := Unit (Units.Table (Main_Unit).Cunit);
803
         S : Node_Id;
804
 
805
         procedure M_Parameters;
806
         --  Output parameters for main program line
807
 
808
         ------------------
809
         -- M_Parameters --
810
         ------------------
811
 
812
         procedure M_Parameters is
813
         begin
814
            if Main_Priority (Main_Unit) /= Default_Main_Priority then
815
               Write_Info_Char (' ');
816
               Write_Info_Nat (Main_Priority (Main_Unit));
817
            end if;
818
 
819
            if Opt.Time_Slice_Set then
820
               Write_Info_Str (" T=");
821
               Write_Info_Nat (Opt.Time_Slice_Value);
822
            end if;
823
 
824
            Write_Info_Str (" W=");
825
            Write_Info_Char
826
              (WC_Encoding_Letters (Wide_Character_Encoding_Method));
827
 
828
            Write_Info_EOL;
829
         end M_Parameters;
830
 
831
      --  Start of processing for Output_Main_Program_Line
832
 
833
      begin
834
         if Nkind (U) = N_Subprogram_Body
835
           or else
836
             (Nkind (U) = N_Package_Body
837
               and then
838
                 Nkind (Original_Node (U)) in N_Subprogram_Instantiation)
839
         then
840
            --  If the unit is a subprogram instance, the entity for the
841
            --  subprogram is the alias of the visible entity, which is the
842
            --  related instance of the wrapper package. We retrieve the
843
            --  subprogram declaration of the desired entity.
844
 
845
            if Nkind (U) = N_Package_Body then
846
               U := Parent (Parent (
847
                   Alias (Related_Instance (Defining_Unit_Name
848
                     (Specification (Unit (Library_Unit (Parent (U)))))))));
849
            end if;
850
 
851
            S := Specification (U);
852
 
853
            if not Present (Parameter_Specifications (S)) then
854
               if Nkind (S) = N_Procedure_Specification then
855
                  Write_Info_Initiate ('M');
856
                  Write_Info_Str (" P");
857
                  M_Parameters;
858
 
859
               else
860
                  declare
861
                     Nam : Node_Id := Defining_Unit_Name (S);
862
 
863
                  begin
864
                     --  If it is a child unit, get its simple name
865
 
866
                     if Nkind (Nam) = N_Defining_Program_Unit_Name then
867
                        Nam := Defining_Identifier (Nam);
868
                     end if;
869
 
870
                     if Is_Integer_Type (Etype (Nam)) then
871
                        Write_Info_Initiate ('M');
872
                        Write_Info_Str (" F");
873
                        M_Parameters;
874
                     end if;
875
                  end;
876
               end if;
877
            end if;
878
         end if;
879
      end Output_Main_Program_Line;
880
 
881
      --  Write command argmument ('A') lines
882
 
883
      for A in 1 .. Compilation_Switches.Last loop
884
         Write_Info_Initiate ('A');
885
         Write_Info_Char (' ');
886
         Write_Info_Str (Compilation_Switches.Table (A).all);
887
         Write_Info_Terminate;
888
      end loop;
889
 
890
      --  Output parameters ('P') line
891
 
892
      Write_Info_Initiate ('P');
893
 
894
      if Compilation_Errors then
895
         Write_Info_Str (" CE");
896
      end if;
897
 
898
      if Opt.Detect_Blocking then
899
         Write_Info_Str (" DB");
900
      end if;
901
 
902
      if Opt.Float_Format /= ' ' then
903
         Write_Info_Str (" F");
904
 
905
         if Opt.Float_Format = 'I' then
906
            Write_Info_Char ('I');
907
 
908
         elsif Opt.Float_Format_Long = 'D' then
909
            Write_Info_Char ('D');
910
 
911
         else
912
            Write_Info_Char ('G');
913
         end if;
914
      end if;
915
 
916
      if Tasking_Used
917
        and then not Is_Predefined_File_Name (Unit_File_Name (Main_Unit))
918
      then
919
         if Locking_Policy /= ' ' then
920
            Write_Info_Str  (" L");
921
            Write_Info_Char (Locking_Policy);
922
         end if;
923
 
924
         if Queuing_Policy /= ' ' then
925
            Write_Info_Str  (" Q");
926
            Write_Info_Char (Queuing_Policy);
927
         end if;
928
 
929
         if Task_Dispatching_Policy /= ' ' then
930
            Write_Info_Str  (" T");
931
            Write_Info_Char (Task_Dispatching_Policy);
932
            Write_Info_Char (' ');
933
         end if;
934
      end if;
935
 
936
      if not Object then
937
         Write_Info_Str (" NO");
938
      end if;
939
 
940
      if No_Run_Time_Mode then
941
         Write_Info_Str (" NR");
942
      end if;
943
 
944
      if Normalize_Scalars then
945
         Write_Info_Str (" NS");
946
      end if;
947
 
948
      if Sec_Stack_Used then
949
         Write_Info_Str (" SS");
950
      end if;
951
 
952
      if Unreserve_All_Interrupts then
953
         Write_Info_Str (" UA");
954
      end if;
955
 
956
      if Exception_Mechanism = Back_End_Exceptions then
957
         Write_Info_Str (" ZX");
958
      end if;
959
 
960
      Write_Info_EOL;
961
 
962
      --  Before outputting the restrictions line, update the setting of
963
      --  the No_Elaboration_Code flag. Violations of this restriction
964
      --  cannot be detected until after the backend has been called since
965
      --  it is the backend that sets this flag. We have to check all units
966
      --  for which we have generated code
967
 
968
      for Unit in Units.First .. Last_Unit loop
969
         if Units.Table (Unit).Generate_Code
970
           or else Unit = Main_Unit
971
         then
972
            if not Has_No_Elaboration_Code (Cunit (Unit)) then
973
               Main_Restrictions.Violated (No_Elaboration_Code) := True;
974
            end if;
975
         end if;
976
      end loop;
977
 
978
      --  Output first restrictions line
979
 
980
      Write_Info_Initiate ('R');
981
      Write_Info_Char (' ');
982
 
983
      --  First the information for the boolean restrictions
984
 
985
      for R in All_Boolean_Restrictions loop
986
         if Main_Restrictions.Set (R)
987
           and then not Restriction_Warnings (R)
988
         then
989
            Write_Info_Char ('r');
990
         elsif Main_Restrictions.Violated (R) then
991
            Write_Info_Char ('v');
992
         else
993
            Write_Info_Char ('n');
994
         end if;
995
      end loop;
996
 
997
      --  And now the information for the parameter restrictions
998
 
999
      for RP in All_Parameter_Restrictions loop
1000
         if Main_Restrictions.Set (RP)
1001
           and then not Restriction_Warnings (RP)
1002
         then
1003
            Write_Info_Char ('r');
1004
            Write_Info_Nat (Nat (Main_Restrictions.Value (RP)));
1005
         else
1006
            Write_Info_Char ('n');
1007
         end if;
1008
 
1009
         if not Main_Restrictions.Violated (RP)
1010
           or else RP not in Checked_Parameter_Restrictions
1011
         then
1012
            Write_Info_Char ('n');
1013
         else
1014
            Write_Info_Char ('v');
1015
            Write_Info_Nat (Nat (Main_Restrictions.Count (RP)));
1016
 
1017
            if Main_Restrictions.Unknown (RP) then
1018
               Write_Info_Char ('+');
1019
            end if;
1020
         end if;
1021
      end loop;
1022
 
1023
      Write_Info_EOL;
1024
 
1025
      --  Output R lines for No_Dependence entries
1026
 
1027
      for J in No_Dependence.First .. No_Dependence.Last loop
1028
         if In_Extended_Main_Source_Unit (No_Dependence.Table (J).Unit)
1029
           and then not No_Dependence.Table (J).Warn
1030
         then
1031
            Write_Info_Initiate ('R');
1032
            Write_Info_Char (' ');
1033
            Write_Unit_Name (No_Dependence.Table (J).Unit);
1034
            Write_Info_EOL;
1035
         end if;
1036
      end loop;
1037
 
1038
      --  Output interrupt state lines
1039
 
1040
      for J in Interrupt_States.First .. Interrupt_States.Last loop
1041
         Write_Info_Initiate ('I');
1042
         Write_Info_Char (' ');
1043
         Write_Info_Nat (Interrupt_States.Table (J).Interrupt_Number);
1044
         Write_Info_Char (' ');
1045
         Write_Info_Char (Interrupt_States.Table (J).Interrupt_State);
1046
         Write_Info_Char (' ');
1047
         Write_Info_Nat
1048
           (Nat (Get_Logical_Line_Number
1049
                   (Interrupt_States.Table (J).Pragma_Loc)));
1050
         Write_Info_EOL;
1051
      end loop;
1052
 
1053
      --  Loop through file table to output information for all units for which
1054
      --  we have generated code, as marked by the Generate_Code flag.
1055
 
1056
      for Unit in Units.First .. Last_Unit loop
1057
         if Units.Table (Unit).Generate_Code
1058
           or else Unit = Main_Unit
1059
         then
1060
            Write_Info_EOL; -- blank line
1061
            Write_Unit_Information (Unit);
1062
         end if;
1063
      end loop;
1064
 
1065
      Write_Info_EOL; -- blank line
1066
 
1067
      --  Output external version reference lines
1068
 
1069
      for J in 1 .. Version_Ref.Last loop
1070
         Write_Info_Initiate ('E');
1071
         Write_Info_Char (' ');
1072
 
1073
         for K in 1 .. String_Length (Version_Ref.Table (J)) loop
1074
            Write_Info_Char_Code (Get_String_Char (Version_Ref.Table (J), K));
1075
         end loop;
1076
 
1077
         Write_Info_EOL;
1078
      end loop;
1079
 
1080
      --  Prepare to output the source dependency lines
1081
 
1082
      declare
1083
         Unum : Unit_Number_Type;
1084
         --  Number of unit being output
1085
 
1086
         Sind : Source_File_Index;
1087
         --  Index of corresponding source file
1088
 
1089
         Fname : File_Name_Type;
1090
 
1091
      begin
1092
         for J in 1 .. Num_Sdep loop
1093
            Unum := Sdep_Table (J);
1094
            Units.Table (Unum).Dependency_Num := J;
1095
            Sind := Units.Table (Unum).Source_Index;
1096
 
1097
            Write_Info_Initiate ('D');
1098
            Write_Info_Char (' ');
1099
 
1100
            --  Normal case of a unit entry with a source index
1101
 
1102
            if Sind /= No_Source_File then
1103
               Fname := File_Name (Sind);
1104
 
1105
               --  Ensure that on platforms where the file names are not
1106
               --  case sensitive, the recorded file name is in lower case.
1107
 
1108
               if not File_Names_Case_Sensitive then
1109
                  Get_Name_String (Fname);
1110
                  To_Lower (Name_Buffer (1 .. Name_Len));
1111
                  Fname := Name_Find;
1112
               end if;
1113
 
1114
               Write_Info_Name (Fname);
1115
               Write_Info_Tab (25);
1116
               Write_Info_Str (String (Time_Stamp (Sind)));
1117
               Write_Info_Char (' ');
1118
               Write_Info_Str (Get_Hex_String (Source_Checksum (Sind)));
1119
 
1120
               --  If subunit, add unit name, omitting the %b at the end
1121
 
1122
               if Present (Cunit (Unum))
1123
                 and then Nkind (Unit (Cunit (Unum))) = N_Subunit
1124
               then
1125
                  Get_Decoded_Name_String (Unit_Name (Unum));
1126
                  Write_Info_Char (' ');
1127
                  Write_Info_Str (Name_Buffer (1 .. Name_Len - 2));
1128
               end if;
1129
 
1130
               --  If Source_Reference pragma used output information
1131
 
1132
               if Num_SRef_Pragmas (Sind) > 0 then
1133
                  Write_Info_Char (' ');
1134
 
1135
                  if Num_SRef_Pragmas (Sind) = 1 then
1136
                     Write_Info_Nat (Int (First_Mapped_Line (Sind)));
1137
                  else
1138
                     Write_Info_Nat (0);
1139
                  end if;
1140
 
1141
                  Write_Info_Char (':');
1142
                  Write_Info_Name (Reference_Name (Sind));
1143
               end if;
1144
 
1145
               --  Case where there is no source index (happens for missing
1146
               --  files). In this case we write a dummy time stamp.
1147
 
1148
            else
1149
               Write_Info_Name (Unit_File_Name (Unum));
1150
               Write_Info_Tab (25);
1151
               Write_Info_Str (String (Dummy_Time_Stamp));
1152
               Write_Info_Char (' ');
1153
               Write_Info_Str (Get_Hex_String (0));
1154
            end if;
1155
 
1156
            Write_Info_EOL;
1157
         end loop;
1158
      end;
1159
 
1160
      Output_References;
1161
      Write_Info_Terminate;
1162
      Close_Output_Library_Info;
1163
   end Write_ALI;
1164
 
1165
   ---------------------
1166
   -- Write_Unit_Name --
1167
   ---------------------
1168
 
1169
   procedure Write_Unit_Name (N : Node_Id) is
1170
   begin
1171
      if Nkind (N) = N_Identifier then
1172
         Write_Info_Name (Chars (N));
1173
 
1174
      else
1175
         pragma Assert (Nkind (N) = N_Selected_Component);
1176
         Write_Unit_Name (Prefix (N));
1177
         Write_Info_Char ('.');
1178
         Write_Unit_Name (Selector_Name (N));
1179
      end if;
1180
   end Write_Unit_Name;
1181
 
1182
end Lib.Writ;

powered by: WebSVN 2.1.0

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