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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [ada/] [lib-writ.adb] - Blame information for rev 816

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

powered by: WebSVN 2.1.0

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