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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [ada/] [errout.adb] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                               E R R O U 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
--  Warning! Error messages can be generated during Gigi processing by direct
27
--  calls to error message routines, so it is essential that the processing
28
--  in this body be consistent with the requirements for the Gigi processing
29
--  environment, and that in particular, no disallowed table expansion is
30
--  allowed to occur.
31
 
32
with Atree;    use Atree;
33
with Casing;   use Casing;
34
with Csets;    use Csets;
35
with Debug;    use Debug;
36
with Einfo;    use Einfo;
37
with Erroutc;  use Erroutc;
38
with Fname;    use Fname;
39
with Gnatvsn;  use Gnatvsn;
40
with Hostparm; use Hostparm;
41
with Lib;      use Lib;
42
with Opt;      use Opt;
43
with Nlists;   use Nlists;
44
with Output;   use Output;
45
with Scans;    use Scans;
46
with Sinput;   use Sinput;
47
with Sinfo;    use Sinfo;
48
with Snames;   use Snames;
49
with Stand;    use Stand;
50
with Stylesw;  use Stylesw;
51
with Uname;    use Uname;
52
 
53
package body Errout is
54
 
55
   Errors_Must_Be_Ignored : Boolean := False;
56
   --  Set to True by procedure Set_Ignore_Errors (True), when calls to error
57
   --  message procedures should be ignored (when parsing irrelevant text in
58
   --  sources being preprocessed).
59
 
60
   Finalize_Called : Boolean := False;
61
   --  Set True if the Finalize routine has been called
62
 
63
   Warn_On_Instance : Boolean;
64
   --  Flag set true for warning message to be posted on instance
65
 
66
   ------------------------------------
67
   -- Table of Non-Instance Messages --
68
   ------------------------------------
69
 
70
   --  This table contains an entry for every error message processed by the
71
   --  Error_Msg routine that is not posted on generic (or inlined) instance.
72
   --  As explained in further detail in the Error_Msg procedure body, this
73
   --  table is used to avoid posting redundant messages on instances.
74
 
75
   type NIM_Record is record
76
      Msg : String_Ptr;
77
      Loc : Source_Ptr;
78
   end record;
79
   --  Type used to store text and location of one message
80
 
81
   package Non_Instance_Msgs is new Table.Table (
82
     Table_Component_Type => NIM_Record,
83
     Table_Index_Type     => Int,
84
     Table_Low_Bound      => 1,
85
     Table_Initial        => 100,
86
     Table_Increment      => 100,
87
     Table_Name           => "Non_Instance_Msgs");
88
 
89
   -----------------------
90
   -- Local Subprograms --
91
   -----------------------
92
 
93
   procedure Error_Msg_Internal
94
     (Msg      : String;
95
      Sptr     : Source_Ptr;
96
      Optr     : Source_Ptr;
97
      Msg_Cont : Boolean);
98
   --  This is the low level routine used to post messages after dealing with
99
   --  the issue of messages placed on instantiations (which get broken up
100
   --  into separate calls in Error_Msg). Sptr is the location on which the
101
   --  flag will be placed in the output. In the case where the flag is on
102
   --  the template, this points directly to the template, not to one of the
103
   --  instantiation copies of the template. Optr is the original location
104
   --  used to flag the error, and this may indeed point to an instantiation
105
   --  copy. So typically we can see Optr pointing to the template location
106
   --  in an instantiation copy when Sptr points to the source location of
107
   --  the actual instantiation (i.e the line with the new). Msg_Cont is
108
   --  set true if this is a continuation message.
109
 
110
   function No_Warnings (N : Node_Or_Entity_Id) return Boolean;
111
   --  Determines if warnings should be suppressed for the given node
112
 
113
   function OK_Node (N : Node_Id) return Boolean;
114
   --  Determines if a node is an OK node to place an error message on (return
115
   --  True) or if the error message should be suppressed (return False). A
116
   --  message is suppressed if the node already has an error posted on it,
117
   --  or if it refers to an Etype that has an error posted on it, or if
118
   --  it references an Entity that has an error posted on it.
119
 
120
   procedure Output_Source_Line
121
     (L     : Physical_Line_Number;
122
      Sfile : Source_File_Index;
123
      Errs  : Boolean);
124
   --  Outputs text of source line L, in file S, together with preceding line
125
   --  number, as described above for Output_Line_Number. The Errs parameter
126
   --  indicates if there are errors attached to the line, which forces
127
   --  listing on, even in the presence of pragma List (Off).
128
 
129
   procedure Set_Msg_Insertion_Column;
130
   --  Handle column number insertion (@ insertion character)
131
 
132
   procedure Set_Msg_Insertion_Node;
133
   --  Handle node (name from node) insertion (& insertion character)
134
 
135
   procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr);
136
   --  Handle type reference (right brace insertion character). Flag is the
137
   --  location of the flag, which is provided for the internal call to
138
   --  Set_Msg_Insertion_Line_Number,
139
 
140
   procedure Set_Msg_Insertion_Unit_Name (Suffix : Boolean := True);
141
   --  Handle unit name insertion ($ insertion character). Depending on Boolean
142
   --  parameter Suffix, (spec) or (body) is appended after the unit name.
143
 
144
   procedure Set_Msg_Node (Node : Node_Id);
145
   --  Add the sequence of characters for the name associated with the
146
   --  given node to the current message.
147
 
148
   procedure Set_Msg_Text (Text : String; Flag : Source_Ptr);
149
   --  Add a sequence of characters to the current message. The characters may
150
   --  be one of the special insertion characters (see documentation in spec).
151
   --  Flag is the location at which the error is to be posted, which is used
152
   --  to determine whether or not the # insertion needs a file name. The
153
   --  variables Msg_Buffer, Msglen, Is_Style_Msg, Is_Warning_Msg, and
154
   --  Is_Unconditional_Msg are set on return.
155
 
156
   procedure Set_Posted (N : Node_Id);
157
   --  Sets the Error_Posted flag on the given node, and all its parents
158
   --  that are subexpressions and then on the parent non-subexpression
159
   --  construct that contains the original expression (this reduces the
160
   --  number of cascaded messages). Note that this call only has an effect
161
   --  for a serious error. For a non-serious error, it has no effect.
162
 
163
   procedure Set_Qualification (N : Nat; E : Entity_Id);
164
   --  Outputs up to N levels of qualification for the given entity. For
165
   --  example, the entity A.B.C.D will output B.C. if N = 2.
166
 
167
   function Special_Msg_Delete
168
     (Msg : String;
169
      N   : Node_Or_Entity_Id;
170
      E   : Node_Or_Entity_Id) return Boolean;
171
   --  This function is called from Error_Msg_NEL, passing the message Msg,
172
   --  node N on which the error is to be posted, and the entity or node E
173
   --  to be used for an & insertion in the message if any. The job of this
174
   --  procedure is to test for certain cascaded messages that we would like
175
   --  to suppress. If the message is to be suppressed then we return True.
176
   --  If the message should be generated (the normal case) False is returned.
177
 
178
   procedure Unwind_Internal_Type (Ent : in out Entity_Id);
179
   --  This procedure is given an entity id for an internal type, i.e.
180
   --  a type with an internal name. It unwinds the type to try to get
181
   --  to something reasonably printable, generating prefixes like
182
   --  "subtype of", "access to", etc along the way in the buffer. The
183
   --  value in Ent on return is the final name to be printed. Hopefully
184
   --  this is not an internal name, but in some internal name cases, it
185
   --  is an internal name, and has to be printed anyway (although in this
186
   --  case the message has been killed if possible). The global variable
187
   --  Class_Flag is set to True if the resulting entity should have
188
   --  'Class appended to its name (see Add_Class procedure), and is
189
   --  otherwise unchanged.
190
 
191
   procedure VMS_Convert;
192
   --  This procedure has no effect if called when the host is not OpenVMS.
193
   --  If the host is indeed OpenVMS, then the error message stored in
194
   --  Msg_Buffer is scanned for appearances of switch names which need
195
   --  converting to corresponding VMS qualifier names. See Gnames/Vnames
196
   --  table in Errout spec for precise definition of the conversion that
197
   --  is performed by this routine in OpenVMS mode.
198
 
199
   -----------------------
200
   -- Change_Error_Text --
201
   -----------------------
202
 
203
   procedure Change_Error_Text (Error_Id : Error_Msg_Id; New_Msg : String) is
204
      Save_Next : Error_Msg_Id;
205
      Err_Id    : Error_Msg_Id := Error_Id;
206
 
207
   begin
208
      Set_Msg_Text (New_Msg, Errors.Table (Error_Id).Sptr);
209
      Errors.Table (Error_Id).Text := new String'(Msg_Buffer (1 .. Msglen));
210
 
211
      --  If in immediate error message mode, output modified error message now
212
      --  This is just a bit tricky, because we want to output just a single
213
      --  message, and the messages we modified is already linked in. We solve
214
      --  this by temporarily resetting its forward pointer to empty.
215
 
216
      if Debug_Flag_OO then
217
         Save_Next := Errors.Table (Error_Id).Next;
218
         Errors.Table (Error_Id).Next := No_Error_Msg;
219
         Write_Eol;
220
         Output_Source_Line
221
           (Errors.Table (Error_Id).Line, Errors.Table (Error_Id).Sfile, True);
222
         Output_Error_Msgs (Err_Id);
223
         Errors.Table (Error_Id).Next := Save_Next;
224
      end if;
225
   end Change_Error_Text;
226
 
227
   ------------------------
228
   -- Compilation_Errors --
229
   ------------------------
230
 
231
   function Compilation_Errors return Boolean is
232
   begin
233
      if not Finalize_Called then
234
         raise Program_Error;
235
      else
236
         return Erroutc.Compilation_Errors;
237
      end if;
238
   end Compilation_Errors;
239
 
240
   ---------------
241
   -- Error_Msg --
242
   ---------------
243
 
244
   --  Error_Msg posts a flag at the given location, except that if the
245
   --  Flag_Location points within a generic template and corresponds
246
   --  to an instantiation of this generic template, then the actual
247
   --  message will be posted on the generic instantiation, along with
248
   --  additional messages referencing the generic declaration.
249
 
250
   procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is
251
      Sindex : Source_File_Index;
252
      --  Source index for flag location
253
 
254
      Orig_Loc : Source_Ptr;
255
      --  Original location of Flag_Location (i.e. location in original
256
      --  template in instantiation case, otherwise unchanged).
257
 
258
   begin
259
      --  It is a fatal error to issue an error message when scanning from
260
      --  the internal source buffer (see Sinput for further documentation)
261
 
262
      pragma Assert (Sinput.Source /= Internal_Source_Ptr);
263
 
264
      --  Return if all errors are to be ignored
265
 
266
      if Errors_Must_Be_Ignored then
267
         return;
268
      end if;
269
 
270
      --  If we already have messages, and we are trying to place a message
271
      --  at No_Location or in package Standard, then just ignore the attempt
272
      --  since we assume that what is happening is some cascaded junk. Note
273
      --  that this is safe in the sense that proceeding will surely bomb.
274
 
275
      if Flag_Location < First_Source_Ptr
276
        and then Total_Errors_Detected > 0
277
      then
278
         return;
279
      end if;
280
 
281
      --  Start of processing for new message
282
 
283
      Sindex := Get_Source_File_Index (Flag_Location);
284
      Test_Style_Warning_Serious_Msg (Msg);
285
      Orig_Loc := Original_Location (Flag_Location);
286
 
287
      --  If the current location is in an instantiation, the issue arises
288
      --  of whether to post the message on the template or the instantiation.
289
 
290
      --  The way we decide is to see if we have posted the same message
291
      --  on the template when we compiled the template (the template is
292
      --  always compiled before any instantiations). For this purpose,
293
      --  we use a separate table of messages. The reason we do this is
294
      --  twofold:
295
 
296
      --     First, the messages can get changed by various processing
297
      --     including the insertion of tokens etc, making it hard to
298
      --     do the comparison.
299
 
300
      --     Second, we will suppress a warning on a template if it is
301
      --     not in the current extended source unit. That's reasonable
302
      --     and means we don't want the warning on the instantiation
303
      --     here either, but it does mean that the main error table
304
      --     would not in any case include the message.
305
 
306
      if Flag_Location = Orig_Loc then
307
         Non_Instance_Msgs.Append ((new String'(Msg), Flag_Location));
308
         Warn_On_Instance := False;
309
 
310
      --  Here we have an instance message
311
 
312
      else
313
         --  Delete if debug flag off, and this message duplicates a
314
         --  message already posted on the corresponding template
315
 
316
         if not Debug_Flag_GG then
317
            for J in Non_Instance_Msgs.First .. Non_Instance_Msgs.Last loop
318
               if Msg = Non_Instance_Msgs.Table (J).Msg.all
319
                 and then Non_Instance_Msgs.Table (J).Loc = Orig_Loc
320
               then
321
                  return;
322
               end if;
323
            end loop;
324
         end if;
325
 
326
         --  No duplicate, so error/warning will be posted on instance
327
 
328
         Warn_On_Instance := Is_Warning_Msg;
329
      end if;
330
 
331
      --  Ignore warning message that is suppressed for this location. Note
332
      --  that style checks are not considered warning messages for this
333
      --  purpose.
334
 
335
      if Is_Warning_Msg and then Warnings_Suppressed (Orig_Loc) then
336
         return;
337
 
338
      --  For style messages, check too many messages so far
339
 
340
      elsif Is_Style_Msg
341
        and then Maximum_Messages /= 0
342
        and then Warnings_Detected >= Maximum_Messages
343
      then
344
         return;
345
      end if;
346
 
347
      --  The idea at this stage is that we have two kinds of messages
348
 
349
      --  First, we have those messages that are to be placed as requested at
350
      --  Flag_Location. This includes messages that have nothing to do with
351
      --  generics, and also messages placed on generic templates that reflect
352
      --  an error in the template itself. For such messages we simply call
353
      --  Error_Msg_Internal to place the message in the requested location.
354
 
355
      if Instantiation (Sindex) = No_Location then
356
         Error_Msg_Internal (Msg, Flag_Location, Flag_Location, False);
357
         return;
358
      end if;
359
 
360
      --  If we are trying to flag an error in an instantiation, we may have
361
      --  a generic contract violation. What we generate in this case is:
362
 
363
      --     instantiation error at ...
364
      --     original error message
365
 
366
      --  or
367
 
368
      --     warning: in instantiation at
369
      --     warning: original warning message
370
 
371
      --  All these messages are posted at the location of the top level
372
      --  instantiation. If there are nested instantiations, then the
373
      --  instantiation error message can be repeated, pointing to each
374
      --  of the relevant instantiations.
375
 
376
      --  Note: the instantiation mechanism is also shared for inlining
377
      --  of subprogram bodies when front end inlining is done. In this
378
      --  case the messages have the form:
379
 
380
      --     in inlined body at ...
381
      --     original error message
382
 
383
      --  or
384
 
385
      --     warning: in inlined body at
386
      --     warning: original warning message
387
 
388
      --  OK, this is the case where we have an instantiation error, and
389
      --  we need to generate the error on the instantiation, rather than
390
      --  on the template.
391
 
392
      declare
393
         Actual_Error_Loc : Source_Ptr;
394
         --  Location of outer level instantiation in instantiation case, or
395
         --  just a copy of Flag_Location in the normal case. This is the
396
         --  location where all error messages will actually be posted.
397
 
398
         Save_Error_Msg_Sloc : constant Source_Ptr := Error_Msg_Sloc;
399
         --  Save possible location set for caller's message. We need to
400
         --  use Error_Msg_Sloc for the location of the instantiation error
401
         --  but we have to preserve a possible original value.
402
 
403
         X : Source_File_Index;
404
 
405
         Msg_Cont_Status : Boolean;
406
         --  Used to label continuation lines in instantiation case with
407
         --  proper Msg_Cont status.
408
 
409
      begin
410
         --  Loop to find highest level instantiation, where all error
411
         --  messages will be placed.
412
 
413
         X := Sindex;
414
         loop
415
            Actual_Error_Loc := Instantiation (X);
416
            X := Get_Source_File_Index (Actual_Error_Loc);
417
            exit when Instantiation (X) = No_Location;
418
         end loop;
419
 
420
         --  Since we are generating the messages at the instantiation
421
         --  point in any case, we do not want the references to the
422
         --  bad lines in the instance to be annotated with the location
423
         --  of the instantiation.
424
 
425
         Suppress_Instance_Location := True;
426
         Msg_Cont_Status := False;
427
 
428
         --  Loop to generate instantiation messages
429
 
430
         Error_Msg_Sloc := Flag_Location;
431
         X := Get_Source_File_Index (Flag_Location);
432
 
433
         while Instantiation (X) /= No_Location loop
434
 
435
            --  Suppress instantiation message on continuation lines
436
 
437
            if Msg (Msg'First) /= '\' then
438
 
439
               --  Case of inlined body
440
 
441
               if Inlined_Body (X) then
442
                  if Is_Warning_Msg or else Is_Style_Msg then
443
                     Error_Msg_Internal
444
                       ("?in inlined body #",
445
                        Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
446
 
447
                  else
448
                     Error_Msg_Internal
449
                       ("error in inlined body #",
450
                        Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
451
                  end if;
452
 
453
               --  Case of generic instantiation
454
 
455
               else
456
                  if Is_Warning_Msg or else Is_Style_Msg then
457
                     Error_Msg_Internal
458
                       ("?in instantiation #",
459
                        Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
460
 
461
                  else
462
                     Error_Msg_Internal
463
                       ("instantiation error #",
464
                        Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
465
                  end if;
466
               end if;
467
            end if;
468
 
469
            Error_Msg_Sloc := Instantiation (X);
470
            X := Get_Source_File_Index (Error_Msg_Sloc);
471
            Msg_Cont_Status := True;
472
         end loop;
473
 
474
         Suppress_Instance_Location := False;
475
         Error_Msg_Sloc := Save_Error_Msg_Sloc;
476
 
477
         --  Here we output the original message on the outer instantiation
478
 
479
         Error_Msg_Internal
480
           (Msg, Actual_Error_Loc, Flag_Location, Msg_Cont_Status);
481
      end;
482
   end Error_Msg;
483
 
484
   ------------------
485
   -- Error_Msg_AP --
486
   ------------------
487
 
488
   procedure Error_Msg_AP (Msg : String) is
489
      S1 : Source_Ptr;
490
      C  : Character;
491
 
492
   begin
493
      --  If we had saved the Scan_Ptr value after scanning the previous
494
      --  token, then we would have exactly the right place for putting
495
      --  the flag immediately at hand. However, that would add at least
496
      --  two instructions to a Scan call *just* to service the possibility
497
      --  of an Error_Msg_AP call. So instead we reconstruct that value.
498
 
499
      --  We have two possibilities, start with Prev_Token_Ptr and skip over
500
      --  the current token, which is made harder by the possibility that this
501
      --  token may be in error, or start with Token_Ptr and work backwards.
502
      --  We used to take the second approach, but it's hard because of
503
      --  comments, and harder still because things that look like comments
504
      --  can appear inside strings. So now we take the first approach.
505
 
506
      --  Note: in the case where there is no previous token, Prev_Token_Ptr
507
      --  is set to Source_First, which is a reasonable position for the
508
      --  error flag in this situation.
509
 
510
      S1 := Prev_Token_Ptr;
511
      C := Source (S1);
512
 
513
      --  If the previous token is a string literal, we need a special approach
514
      --  since there may be white space inside the literal and we don't want
515
      --  to stop on that white space.
516
 
517
      --  Note: since this is an error recovery issue anyway, it is not worth
518
      --  worrying about special UTF_32 line terminator characters here.
519
 
520
      if Prev_Token = Tok_String_Literal then
521
         loop
522
            S1 := S1 + 1;
523
 
524
            if Source (S1) = C then
525
               S1 := S1 + 1;
526
               exit when Source (S1) /= C;
527
            elsif Source (S1) in Line_Terminator then
528
               exit;
529
            end if;
530
         end loop;
531
 
532
      --  Character literal also needs special handling
533
 
534
      elsif Prev_Token = Tok_Char_Literal then
535
         S1 := S1 + 3;
536
 
537
      --  Otherwise we search forward for the end of the current token, marked
538
      --  by a line terminator, white space, a comment symbol or if we bump
539
      --  into the following token (i.e. the current token).
540
 
541
      --  Again, it is not worth worrying about UTF_32 special line terminator
542
      --  characters in this context, since this is only for error recovery.
543
 
544
      else
545
         while Source (S1) not in Line_Terminator
546
           and then Source (S1) /= ' '
547
           and then Source (S1) /= ASCII.HT
548
           and then (Source (S1) /= '-' or else Source (S1 + 1) /= '-')
549
           and then S1 /= Token_Ptr
550
         loop
551
            S1 := S1 + 1;
552
         end loop;
553
      end if;
554
 
555
      --  S1 is now set to the location for the flag
556
 
557
      Error_Msg (Msg, S1);
558
   end Error_Msg_AP;
559
 
560
   ------------------
561
   -- Error_Msg_BC --
562
   ------------------
563
 
564
   procedure Error_Msg_BC (Msg : String) is
565
   begin
566
      --  If we are at end of file, post the flag after the previous token
567
 
568
      if Token = Tok_EOF then
569
         Error_Msg_AP (Msg);
570
 
571
      --  If we are at start of file, post the flag at the current token
572
 
573
      elsif Token_Ptr = Source_First (Current_Source_File) then
574
         Error_Msg_SC (Msg);
575
 
576
      --  If the character before the current token is a space or a horizontal
577
      --  tab, then we place the flag on this character (in the case of a tab
578
      --  we would really like to place it in the "last" character of the tab
579
      --  space, but that it too much trouble to worry about).
580
 
581
      elsif Source (Token_Ptr - 1) = ' '
582
         or else Source (Token_Ptr - 1) = ASCII.HT
583
      then
584
         Error_Msg (Msg, Token_Ptr - 1);
585
 
586
      --  If there is no space or tab before the current token, then there is
587
      --  no room to place the flag before the token, so we place it on the
588
      --  token instead (this happens for example at the start of a line).
589
 
590
      else
591
         Error_Msg (Msg, Token_Ptr);
592
      end if;
593
   end Error_Msg_BC;
594
 
595
   -------------------
596
   -- Error_Msg_CRT --
597
   -------------------
598
 
599
   procedure Error_Msg_CRT (Feature : String; N : Node_Id) is
600
      CNRT : constant String := " not allowed in no run time mode";
601
      CCRT : constant String := " not supported by configuration>";
602
 
603
      S : String (1 .. Feature'Length + 1 + CCRT'Length);
604
      L : Natural;
605
 
606
   begin
607
      S (1) := '|';
608
      S (2 .. Feature'Length + 1) := Feature;
609
      L := Feature'Length + 2;
610
 
611
      if No_Run_Time_Mode then
612
         S (L .. L + CNRT'Length - 1) := CNRT;
613
         L := L + CNRT'Length - 1;
614
 
615
      else pragma Assert (Configurable_Run_Time_Mode);
616
         S (L .. L + CCRT'Length - 1) := CCRT;
617
         L := L + CCRT'Length - 1;
618
      end if;
619
 
620
      Error_Msg_N (S (1 .. L), N);
621
      Configurable_Run_Time_Violations := Configurable_Run_Time_Violations + 1;
622
   end Error_Msg_CRT;
623
 
624
   -----------------
625
   -- Error_Msg_F --
626
   -----------------
627
 
628
   procedure Error_Msg_F (Msg : String; N : Node_Id) is
629
   begin
630
      Error_Msg_NEL (Msg, N, N, Sloc (First_Node (N)));
631
   end Error_Msg_F;
632
 
633
   ------------------
634
   -- Error_Msg_FE --
635
   ------------------
636
 
637
   procedure Error_Msg_FE
638
     (Msg : String;
639
      N   : Node_Id;
640
      E   : Node_Or_Entity_Id)
641
   is
642
   begin
643
      Error_Msg_NEL (Msg, N, E, Sloc (First_Node (N)));
644
   end Error_Msg_FE;
645
 
646
   ------------------------
647
   -- Error_Msg_Internal --
648
   ------------------------
649
 
650
   procedure Error_Msg_Internal
651
     (Msg      : String;
652
      Sptr     : Source_Ptr;
653
      Optr     : Source_Ptr;
654
      Msg_Cont : Boolean)
655
   is
656
      Next_Msg : Error_Msg_Id;
657
      --  Pointer to next message at insertion point
658
 
659
      Prev_Msg : Error_Msg_Id;
660
      --  Pointer to previous message at insertion point
661
 
662
      Temp_Msg : Error_Msg_Id;
663
 
664
      procedure Handle_Serious_Error;
665
      --  Internal procedure to do all error message handling for a serious
666
      --  error message, other than bumping the error counts and arranging
667
      --  for the message to be output.
668
 
669
      --------------------------
670
      -- Handle_Serious_Error --
671
      --------------------------
672
 
673
      procedure Handle_Serious_Error is
674
      begin
675
         --  Turn off code generation if not done already
676
 
677
         if Operating_Mode = Generate_Code then
678
            Operating_Mode := Check_Semantics;
679
            Expander_Active := False;
680
         end if;
681
 
682
         --  Set the fatal error flag in the unit table unless we are
683
         --  in Try_Semantics mode. This stops the semantics from being
684
         --  performed if we find a serious error. This is skipped if we
685
         --  are currently dealing with the configuration pragma file.
686
 
687
         if not Try_Semantics and then Current_Source_Unit /= No_Unit then
688
            Set_Fatal_Error (Get_Source_Unit (Sptr));
689
         end if;
690
      end Handle_Serious_Error;
691
 
692
   --  Start of processing for Error_Msg_Internal
693
 
694
   begin
695
      if Raise_Exception_On_Error /= 0 then
696
         raise Error_Msg_Exception;
697
      end if;
698
 
699
      Continuation := Msg_Cont;
700
      Continuation_New_Line := False;
701
      Suppress_Message := False;
702
      Kill_Message := False;
703
      Set_Msg_Text (Msg, Sptr);
704
 
705
      --  Kill continuation if parent message killed
706
 
707
      if Continuation and Last_Killed then
708
         return;
709
      end if;
710
 
711
      --  Return without doing anything if message is suppressed
712
 
713
      if Suppress_Message
714
        and then not All_Errors_Mode
715
        and then not Is_Warning_Msg
716
        and then Msg (Msg'Last) /= '!'
717
      then
718
         if not Continuation then
719
            Last_Killed := True;
720
         end if;
721
 
722
         return;
723
      end if;
724
 
725
      --  Return without doing anything if message is killed and this
726
      --  is not the first error message. The philosophy is that if we
727
      --  get a weird error message and we already have had a message,
728
      --  then we hope the weird message is a junk cascaded message
729
 
730
      if Kill_Message
731
        and then not All_Errors_Mode
732
        and then Total_Errors_Detected /= 0
733
      then
734
         if not Continuation then
735
            Last_Killed := True;
736
         end if;
737
 
738
         return;
739
      end if;
740
 
741
      --  Special check for warning message to see if it should be output
742
 
743
      if Is_Warning_Msg then
744
 
745
         --  Immediate return if warning message and warnings are suppressed
746
 
747
         if Warnings_Suppressed (Optr) or else Warnings_Suppressed (Sptr) then
748
            Cur_Msg := No_Error_Msg;
749
            return;
750
         end if;
751
 
752
         --  If the flag location is in the main extended source unit
753
         --  then for sure we want the warning since it definitely belongs
754
 
755
         if In_Extended_Main_Source_Unit (Sptr) then
756
            null;
757
 
758
         --  If the flag location is not in the main extended source unit,
759
         --  then we want to eliminate the warning, unless it is in the
760
         --  extended main code unit and we want warnings on the instance.
761
 
762
         elsif In_Extended_Main_Code_Unit (Sptr) and then Warn_On_Instance then
763
            null;
764
 
765
         --  Keep warning if debug flag G set
766
 
767
         elsif Debug_Flag_GG then
768
            null;
769
 
770
         --  Keep warning if message text ends in !!
771
 
772
         elsif Msg (Msg'Last) = '!' and then Msg (Msg'Last - 1) = '!' then
773
            null;
774
 
775
         --  Here is where we delete a warning from a with'ed unit
776
 
777
         else
778
            Cur_Msg := No_Error_Msg;
779
 
780
            if not Continuation then
781
               Last_Killed := True;
782
            end if;
783
 
784
            return;
785
         end if;
786
      end if;
787
 
788
      --  If message is to be ignored in special ignore message mode, this is
789
      --  where we do this special processing, bypassing message output.
790
 
791
      if Ignore_Errors_Enable > 0 then
792
         if Is_Serious_Error then
793
            Handle_Serious_Error;
794
         end if;
795
 
796
         return;
797
      end if;
798
 
799
      --  If error message line length set, and this is a continuation message
800
      --  then all we do is to append the text to the text of the last message
801
      --  with a comma space separator (eliminating a possible (style) or
802
      --  info prefix).
803
 
804
      if Error_Msg_Line_Length /= 0
805
        and then Continuation
806
      then
807
         Cur_Msg := Errors.Last;
808
 
809
         declare
810
            Oldm : String_Ptr := Errors.Table (Cur_Msg).Text;
811
            Newm : String (1 .. Oldm'Last + 2 + Msglen);
812
            Newl : Natural;
813
            M    : Natural;
814
 
815
         begin
816
            --  First copy old message to new one and free it
817
 
818
            Newm (Oldm'Range) := Oldm.all;
819
            Newl := Oldm'Length;
820
            Free (Oldm);
821
 
822
            --  Remove (style) or info: at start of message
823
 
824
            if Msglen > 8 and then Msg_Buffer (1 .. 8) = "(style) " then
825
               M := 9;
826
 
827
            elsif Msglen > 6 and then Msg_Buffer (1 .. 6) = "info: " then
828
               M := 7;
829
 
830
            else
831
               M := 1;
832
            end if;
833
 
834
            --  Now deal with separation between messages. Normally this is
835
            --  simply comma space, but there are some special cases.
836
 
837
            --  If continuation new line, then put actual NL character in msg
838
 
839
            if Continuation_New_Line then
840
               Newl := Newl + 1;
841
               Newm (Newl) := ASCII.LF;
842
 
843
            --  If continuation message is enclosed in parentheses, then
844
            --  special treatment (don't need a comma, and we want to combine
845
            --  successive parenthetical remarks into a single one with
846
            --  separating commas).
847
 
848
            elsif Msg_Buffer (M) = '(' and then Msg_Buffer (Msglen) = ')' then
849
 
850
               --  Case where existing message ends in right paren, remove
851
               --  and separate parenthetical remarks with a comma.
852
 
853
               if Newm (Newl) = ')' then
854
                  Newm (Newl) := ',';
855
                  Msg_Buffer (M) := ' ';
856
 
857
               --  Case where we are adding new parenthetical comment
858
 
859
               else
860
                  Newl := Newl + 1;
861
                  Newm (Newl) := ' ';
862
               end if;
863
 
864
            --  Case where continuation not in parens and no new line
865
 
866
            else
867
               Newm (Newl + 1 .. Newl + 2) := ", ";
868
               Newl := Newl + 2;
869
            end if;
870
 
871
            --  Append new message
872
 
873
            Newm (Newl + 1 .. Newl + Msglen - M + 1) :=
874
              Msg_Buffer (M .. Msglen);
875
            Newl := Newl + Msglen - M + 1;
876
            Errors.Table (Cur_Msg).Text := new String'(Newm (1 .. Newl));
877
         end;
878
 
879
         return;
880
      end if;
881
 
882
      --  Otherwise build error message object for new message
883
 
884
      Errors.Append
885
        ((Text     => new String'(Msg_Buffer (1 .. Msglen)),
886
          Next     => No_Error_Msg,
887
          Sptr     => Sptr,
888
          Optr     => Optr,
889
          Sfile    => Get_Source_File_Index (Sptr),
890
          Line     => Get_Physical_Line_Number (Sptr),
891
          Col      => Get_Column_Number (Sptr),
892
          Warn     => Is_Warning_Msg,
893
          Style    => Is_Style_Msg,
894
          Serious  => Is_Serious_Error,
895
          Uncond   => Is_Unconditional_Msg,
896
          Msg_Cont => Continuation,
897
          Deleted  => False));
898
      Cur_Msg := Errors.Last;
899
 
900
      --  If immediate errors mode set, output error message now. Also output
901
      --  now if the -d1 debug flag is set (so node number message comes out
902
      --  just before actual error message)
903
 
904
      if Debug_Flag_OO or else Debug_Flag_1 then
905
         Write_Eol;
906
         Output_Source_Line
907
           (Errors.Table (Cur_Msg).Line, Errors.Table (Cur_Msg).Sfile, True);
908
         Temp_Msg := Cur_Msg;
909
         Output_Error_Msgs (Temp_Msg);
910
 
911
      --  If not in immediate errors mode, then we insert the message in the
912
      --  error chain for later output by Finalize. The messages are sorted
913
      --  first by unit (main unit comes first), and within a unit by source
914
      --  location (earlier flag location first in the chain).
915
 
916
      else
917
         --  First a quick check, does this belong at the very end of the chain
918
         --  of error messages. This saves a lot of time in the normal case if
919
         --  there are lots of messages.
920
 
921
         if Last_Error_Msg /= No_Error_Msg
922
           and then Errors.Table (Cur_Msg).Sfile =
923
                    Errors.Table (Last_Error_Msg).Sfile
924
           and then (Sptr > Errors.Table (Last_Error_Msg).Sptr
925
                       or else
926
                          (Sptr = Errors.Table (Last_Error_Msg).Sptr
927
                             and then
928
                               Optr > Errors.Table (Last_Error_Msg).Optr))
929
         then
930
            Prev_Msg := Last_Error_Msg;
931
            Next_Msg := No_Error_Msg;
932
 
933
         --  Otherwise do a full sequential search for the insertion point
934
 
935
         else
936
            Prev_Msg := No_Error_Msg;
937
            Next_Msg := First_Error_Msg;
938
            while Next_Msg /= No_Error_Msg loop
939
               exit when
940
                 Errors.Table (Cur_Msg).Sfile < Errors.Table (Next_Msg).Sfile;
941
 
942
               if Errors.Table (Cur_Msg).Sfile =
943
                    Errors.Table (Next_Msg).Sfile
944
               then
945
                  exit when Sptr < Errors.Table (Next_Msg).Sptr
946
                              or else
947
                                (Sptr = Errors.Table (Next_Msg).Sptr
948
                                   and then
949
                                 Optr < Errors.Table (Next_Msg).Optr);
950
               end if;
951
 
952
               Prev_Msg := Next_Msg;
953
               Next_Msg := Errors.Table (Next_Msg).Next;
954
            end loop;
955
         end if;
956
 
957
         --  Now we insert the new message in the error chain. The insertion
958
         --  point for the message is after Prev_Msg and before Next_Msg.
959
 
960
         --  The possible insertion point for the new message is after Prev_Msg
961
         --  and before Next_Msg. However, this is where we do a special check
962
         --  for redundant parsing messages, defined as messages posted on the
963
         --  same line. The idea here is that probably such messages are junk
964
         --  from the parser recovering. In full errors mode, we don't do this
965
         --  deletion, but otherwise such messages are discarded at this stage.
966
 
967
         if Prev_Msg /= No_Error_Msg
968
           and then Errors.Table (Prev_Msg).Line =
969
                                             Errors.Table (Cur_Msg).Line
970
           and then Errors.Table (Prev_Msg).Sfile =
971
                                             Errors.Table (Cur_Msg).Sfile
972
           and then Compiler_State = Parsing
973
           and then not All_Errors_Mode
974
         then
975
            --  Don't delete unconditional messages and at this stage, don't
976
            --  delete continuation lines (we attempted to delete those earlier
977
            --  if the parent message was deleted.
978
 
979
            if not Errors.Table (Cur_Msg).Uncond
980
              and then not Continuation
981
            then
982
               --  Don't delete if prev msg is warning and new msg is an error.
983
               --  This is because we don't want a real error masked by a
984
               --  warning. In all other cases (that is parse errors for the
985
               --  same line that are not unconditional) we do delete the
986
               --  message. This helps to avoid junk extra messages from
987
               --  cascaded parsing errors
988
 
989
               if not (Errors.Table (Prev_Msg).Warn
990
                         or else
991
                       Errors.Table (Prev_Msg).Style)
992
                 or else
993
                      (Errors.Table (Cur_Msg).Warn
994
                         or else
995
                       Errors.Table (Cur_Msg).Style)
996
               then
997
                  --  All tests passed, delete the message by simply returning
998
                  --  without any further processing.
999
 
1000
                  if not Continuation then
1001
                     Last_Killed := True;
1002
                  end if;
1003
 
1004
                  return;
1005
               end if;
1006
            end if;
1007
         end if;
1008
 
1009
         --  Come here if message is to be inserted in the error chain
1010
 
1011
         if not Continuation then
1012
            Last_Killed := False;
1013
         end if;
1014
 
1015
         if Prev_Msg = No_Error_Msg then
1016
            First_Error_Msg := Cur_Msg;
1017
         else
1018
            Errors.Table (Prev_Msg).Next := Cur_Msg;
1019
         end if;
1020
 
1021
         Errors.Table (Cur_Msg).Next := Next_Msg;
1022
 
1023
         if Next_Msg = No_Error_Msg then
1024
            Last_Error_Msg := Cur_Msg;
1025
         end if;
1026
      end if;
1027
 
1028
      --  Bump appropriate statistics count
1029
 
1030
      if Errors.Table (Cur_Msg).Warn or else Errors.Table (Cur_Msg).Style then
1031
         Warnings_Detected := Warnings_Detected + 1;
1032
 
1033
      else
1034
         Total_Errors_Detected := Total_Errors_Detected + 1;
1035
 
1036
         if Errors.Table (Cur_Msg).Serious then
1037
            Serious_Errors_Detected := Serious_Errors_Detected + 1;
1038
            Handle_Serious_Error;
1039
         end if;
1040
      end if;
1041
 
1042
      --  If too many warnings turn off warnings
1043
 
1044
      if Maximum_Messages /= 0 then
1045
         if Warnings_Detected = Maximum_Messages then
1046
            Warning_Mode := Suppress;
1047
         end if;
1048
 
1049
         --  If too many errors abandon compilation
1050
 
1051
         if Total_Errors_Detected = Maximum_Messages then
1052
            raise Unrecoverable_Error;
1053
         end if;
1054
      end if;
1055
   end Error_Msg_Internal;
1056
 
1057
   -----------------
1058
   -- Error_Msg_N --
1059
   -----------------
1060
 
1061
   procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id) is
1062
   begin
1063
      Error_Msg_NEL (Msg, N, N, Sloc (N));
1064
   end Error_Msg_N;
1065
 
1066
   ------------------
1067
   -- Error_Msg_NE --
1068
   ------------------
1069
 
1070
   procedure Error_Msg_NE
1071
     (Msg : String;
1072
      N   : Node_Or_Entity_Id;
1073
      E   : Node_Or_Entity_Id)
1074
   is
1075
   begin
1076
      Error_Msg_NEL (Msg, N, E, Sloc (N));
1077
   end Error_Msg_NE;
1078
 
1079
   -------------------
1080
   -- Error_Msg_NEL --
1081
   -------------------
1082
 
1083
   procedure Error_Msg_NEL
1084
     (Msg           : String;
1085
      N             : Node_Or_Entity_Id;
1086
      E             : Node_Or_Entity_Id;
1087
      Flag_Location : Source_Ptr)
1088
   is
1089
   begin
1090
      if Special_Msg_Delete (Msg, N, E) then
1091
         return;
1092
      end if;
1093
 
1094
      Test_Style_Warning_Serious_Msg (Msg);
1095
 
1096
      --  Special handling for warning messages
1097
 
1098
      if Is_Warning_Msg then
1099
 
1100
         --  Suppress if no warnings set for either entity or node
1101
 
1102
         if No_Warnings (N) or else No_Warnings (E) then
1103
 
1104
            --  Disable any continuation messages as well
1105
 
1106
            Last_Killed := True;
1107
            return;
1108
         end if;
1109
 
1110
         --  Suppress if inside loop that is known to be null or is probably
1111
         --  null (case where loop executes only if invalid values present).
1112
         --  In either case warnings in the loop are likely to be junk.
1113
 
1114
         declare
1115
            P : Node_Id;
1116
 
1117
         begin
1118
            P := Parent (N);
1119
            while Present (P) loop
1120
               if Nkind (P) = N_Loop_Statement
1121
                 and then Suppress_Loop_Warnings (P)
1122
               then
1123
                  return;
1124
               end if;
1125
 
1126
               P := Parent (P);
1127
            end loop;
1128
         end;
1129
      end if;
1130
 
1131
      --  Test for message to be output
1132
 
1133
      if All_Errors_Mode
1134
        or else Msg (Msg'Last) = '!'
1135
        or else Is_Warning_Msg
1136
        or else OK_Node (N)
1137
        or else (Msg (Msg'First) = '\' and then not Last_Killed)
1138
      then
1139
         Debug_Output (N);
1140
         Error_Msg_Node_1 := E;
1141
         Error_Msg (Msg, Flag_Location);
1142
 
1143
      else
1144
         Last_Killed := True;
1145
      end if;
1146
 
1147
      if not (Is_Warning_Msg or Is_Style_Msg) then
1148
         Set_Posted (N);
1149
      end if;
1150
   end Error_Msg_NEL;
1151
 
1152
   ------------------
1153
   -- Error_Msg_NW --
1154
   ------------------
1155
 
1156
   procedure Error_Msg_NW
1157
     (Eflag : Boolean;
1158
      Msg   : String;
1159
      N     : Node_Or_Entity_Id)
1160
   is
1161
   begin
1162
      if Eflag
1163
        and then In_Extended_Main_Source_Unit (N)
1164
        and then Comes_From_Source (N)
1165
      then
1166
         Error_Msg_NEL (Msg, N, N, Sloc (N));
1167
      end if;
1168
   end Error_Msg_NW;
1169
 
1170
   -----------------
1171
   -- Error_Msg_S --
1172
   -----------------
1173
 
1174
   procedure Error_Msg_S (Msg : String) is
1175
   begin
1176
      Error_Msg (Msg, Scan_Ptr);
1177
   end Error_Msg_S;
1178
 
1179
   ------------------
1180
   -- Error_Msg_SC --
1181
   ------------------
1182
 
1183
   procedure Error_Msg_SC (Msg : String) is
1184
   begin
1185
      --  If we are at end of file, post the flag after the previous token
1186
 
1187
      if Token = Tok_EOF then
1188
         Error_Msg_AP (Msg);
1189
 
1190
      --  For all other cases the message is posted at the current token
1191
      --  pointer position
1192
 
1193
      else
1194
         Error_Msg (Msg, Token_Ptr);
1195
      end if;
1196
   end Error_Msg_SC;
1197
 
1198
   ------------------
1199
   -- Error_Msg_SP --
1200
   ------------------
1201
 
1202
   procedure Error_Msg_SP (Msg : String) is
1203
   begin
1204
      --  Note: in the case where there is no previous token, Prev_Token_Ptr
1205
      --  is set to Source_First, which is a reasonable position for the
1206
      --  error flag in this situation
1207
 
1208
      Error_Msg (Msg, Prev_Token_Ptr);
1209
   end Error_Msg_SP;
1210
 
1211
   --------------
1212
   -- Finalize --
1213
   --------------
1214
 
1215
   procedure Finalize (Last_Call : Boolean) is
1216
      Cur : Error_Msg_Id;
1217
      Nxt : Error_Msg_Id;
1218
      F   : Error_Msg_Id;
1219
 
1220
   begin
1221
      --  Eliminate any duplicated error messages from the list. This is
1222
      --  done after the fact to avoid problems with Change_Error_Text.
1223
 
1224
      Cur := First_Error_Msg;
1225
      while Cur /= No_Error_Msg loop
1226
         Nxt := Errors.Table (Cur).Next;
1227
 
1228
         F := Nxt;
1229
         while F /= No_Error_Msg
1230
           and then Errors.Table (F).Sptr = Errors.Table (Cur).Sptr
1231
         loop
1232
            Check_Duplicate_Message (Cur, F);
1233
            F := Errors.Table (F).Next;
1234
         end loop;
1235
 
1236
         Cur := Nxt;
1237
      end loop;
1238
 
1239
      --  Mark any messages suppressed by specific warnings as Deleted
1240
 
1241
      Cur := First_Error_Msg;
1242
      while Cur /= No_Error_Msg loop
1243
         if not Errors.Table (Cur).Deleted
1244
           and then Warning_Specifically_Suppressed
1245
                     (Errors.Table (Cur).Sptr,
1246
                      Errors.Table (Cur).Text)
1247
         then
1248
            Errors.Table (Cur).Deleted := True;
1249
            Warnings_Detected := Warnings_Detected - 1;
1250
         end if;
1251
 
1252
         Cur := Errors.Table (Cur).Next;
1253
      end loop;
1254
 
1255
      Finalize_Called := True;
1256
 
1257
      --  Check consistency of specific warnings (may add warnings). We only
1258
      --  do this on the last call, after all possible warnings are posted.
1259
 
1260
      if Last_Call then
1261
         Validate_Specific_Warnings (Error_Msg'Access);
1262
      end if;
1263
   end Finalize;
1264
 
1265
   ----------------
1266
   -- First_Node --
1267
   ----------------
1268
 
1269
   function First_Node (C : Node_Id) return Node_Id is
1270
      L        : constant Source_Ptr        := Sloc (Original_Node (C));
1271
      Sfile    : constant Source_File_Index := Get_Source_File_Index (L);
1272
      Earliest : Node_Id;
1273
      Eloc     : Source_Ptr;
1274
 
1275
      function Test_Earlier (N : Node_Id) return Traverse_Result;
1276
      --  Function applied to every node in the construct
1277
 
1278
      procedure Search_Tree_First is new Traverse_Proc (Test_Earlier);
1279
      --  Create traversal procedure
1280
 
1281
      ------------------
1282
      -- Test_Earlier --
1283
      ------------------
1284
 
1285
      function Test_Earlier (N : Node_Id) return Traverse_Result is
1286
         Loc : constant Source_Ptr := Sloc (Original_Node (N));
1287
 
1288
      begin
1289
         --  Check for earlier. The tests for being in the same file ensures
1290
         --  against strange cases of foreign code somehow being present. We
1291
         --  don't want wild placement of messages if that happens, so it is
1292
         --  best to just ignore this situation.
1293
 
1294
         if Loc < Eloc
1295
           and then Get_Source_File_Index (Loc) = Sfile
1296
         then
1297
            Earliest := Original_Node (N);
1298
            Eloc     := Loc;
1299
         end if;
1300
 
1301
         return OK_Orig;
1302
      end Test_Earlier;
1303
 
1304
   --  Start of processing for First_Node
1305
 
1306
   begin
1307
      Earliest := Original_Node (C);
1308
      Eloc := Sloc (Earliest);
1309
      Search_Tree_First (Original_Node (C));
1310
      return Earliest;
1311
   end First_Node;
1312
 
1313
   ----------------
1314
   -- First_Sloc --
1315
   ----------------
1316
 
1317
   function First_Sloc (N : Node_Id) return Source_Ptr is
1318
      SI : constant Source_File_Index := Source_Index (Get_Source_Unit (N));
1319
      SF : constant Source_Ptr        := Source_First (SI);
1320
      F  : Node_Id;
1321
      S  : Source_Ptr;
1322
 
1323
   begin
1324
      F := First_Node (N);
1325
      S := Sloc (F);
1326
 
1327
      --  The following circuit is a bit subtle. When we have parenthesized
1328
      --  expressions, then the Sloc will not record the location of the
1329
      --  paren, but we would like to post the flag on the paren. So what
1330
      --  we do is to crawl up the tree from the First_Node, adjusting the
1331
      --  Sloc value for any parentheses we know are present. Yes, we know
1332
      --  this circuit is not 100% reliable (e.g. because we don't record
1333
      --  all possible paren level values), but this is only for an error
1334
      --  message so it is good enough.
1335
 
1336
      Node_Loop : loop
1337
         Paren_Loop : for J in 1 .. Paren_Count (F) loop
1338
 
1339
            --  We don't look more than 12 characters behind the current
1340
            --  location, and in any case not past the front of the source.
1341
 
1342
            Search_Loop : for K in 1 .. 12 loop
1343
               exit Search_Loop when S = SF;
1344
 
1345
               if Source_Text (SI) (S - 1) = '(' then
1346
                  S := S - 1;
1347
                  exit Search_Loop;
1348
 
1349
               elsif Source_Text (SI) (S - 1) <= ' ' then
1350
                  S := S - 1;
1351
 
1352
               else
1353
                  exit Search_Loop;
1354
               end if;
1355
            end loop Search_Loop;
1356
         end loop Paren_Loop;
1357
 
1358
         exit Node_Loop when F = N;
1359
         F := Parent (F);
1360
         exit Node_Loop when Nkind (F) not in N_Subexpr;
1361
      end loop Node_Loop;
1362
 
1363
      return S;
1364
   end First_Sloc;
1365
 
1366
   ----------------
1367
   -- Initialize --
1368
   ----------------
1369
 
1370
   procedure Initialize is
1371
   begin
1372
      Errors.Init;
1373
      First_Error_Msg := No_Error_Msg;
1374
      Last_Error_Msg := No_Error_Msg;
1375
      Serious_Errors_Detected := 0;
1376
      Total_Errors_Detected := 0;
1377
      Warnings_Detected := 0;
1378
      Cur_Msg := No_Error_Msg;
1379
      List_Pragmas.Init;
1380
 
1381
      --  Initialize warnings table, if all warnings are suppressed, supply
1382
      --  an initial dummy entry covering all possible source locations.
1383
 
1384
      Warnings.Init;
1385
      Specific_Warnings.Init;
1386
 
1387
      if Warning_Mode = Suppress then
1388
         Warnings.Append
1389
           ((Start => Source_Ptr'First, Stop => Source_Ptr'Last));
1390
      end if;
1391
   end Initialize;
1392
 
1393
   -----------------
1394
   -- No_Warnings --
1395
   -----------------
1396
 
1397
   function No_Warnings (N : Node_Or_Entity_Id) return Boolean is
1398
   begin
1399
      if Error_Posted (N) then
1400
         return True;
1401
 
1402
      elsif Nkind (N) in N_Entity and then Has_Warnings_Off (N) then
1403
         return True;
1404
 
1405
      elsif Is_Entity_Name (N)
1406
        and then Present (Entity (N))
1407
        and then Has_Warnings_Off (Entity (N))
1408
      then
1409
         return True;
1410
 
1411
      else
1412
         return False;
1413
      end if;
1414
   end No_Warnings;
1415
 
1416
   -------------
1417
   -- OK_Node --
1418
   -------------
1419
 
1420
   function OK_Node (N : Node_Id) return Boolean is
1421
      K : constant Node_Kind := Nkind (N);
1422
 
1423
   begin
1424
      if Error_Posted (N) then
1425
         return False;
1426
 
1427
      elsif K in N_Has_Etype
1428
        and then Present (Etype (N))
1429
        and then Error_Posted (Etype (N))
1430
      then
1431
         return False;
1432
 
1433
      elsif (K in N_Op
1434
              or else K = N_Attribute_Reference
1435
              or else K = N_Character_Literal
1436
              or else K = N_Expanded_Name
1437
              or else K = N_Identifier
1438
              or else K = N_Operator_Symbol)
1439
        and then Present (Entity (N))
1440
        and then Error_Posted (Entity (N))
1441
      then
1442
         return False;
1443
      else
1444
         return True;
1445
      end if;
1446
   end OK_Node;
1447
 
1448
   ---------------------
1449
   -- Output_Messages --
1450
   ---------------------
1451
 
1452
   procedure Output_Messages is
1453
      E        : Error_Msg_Id;
1454
      Err_Flag : Boolean;
1455
 
1456
      procedure Write_Error_Summary;
1457
      --  Write error summary
1458
 
1459
      procedure Write_Header (Sfile : Source_File_Index);
1460
      --  Write header line (compiling or checking given file)
1461
 
1462
      procedure Write_Max_Errors;
1463
      --  Write message if max errors reached
1464
 
1465
      -------------------------
1466
      -- Write_Error_Summary --
1467
      -------------------------
1468
 
1469
      procedure Write_Error_Summary is
1470
      begin
1471
         --  Extra blank line if error messages or source listing were output
1472
 
1473
         if Total_Errors_Detected + Warnings_Detected > 0
1474
           or else Full_List
1475
         then
1476
            Write_Eol;
1477
         end if;
1478
 
1479
         --  Message giving number of lines read and number of errors detected.
1480
         --  This normally goes to Standard_Output. The exception is when brief
1481
         --  mode is not set, verbose mode (or full list mode) is set, and
1482
         --  there are errors. In this case we send the message to standard
1483
         --  error to make sure that *something* appears on standard error in
1484
         --  an error situation.
1485
 
1486
         --  Formerly, only the "# errors" suffix was sent to stderr, whereas
1487
         --  "# lines:" appeared on stdout. This caused problems on VMS when
1488
         --  the stdout buffer was flushed, giving an extra line feed after
1489
         --  the prefix.
1490
 
1491
         if Total_Errors_Detected + Warnings_Detected /= 0
1492
           and then not Brief_Output
1493
           and then (Verbose_Mode or Full_List)
1494
         then
1495
            Set_Standard_Error;
1496
         end if;
1497
 
1498
         --  Message giving total number of lines
1499
 
1500
         Write_Str (" ");
1501
         Write_Int (Num_Source_Lines (Main_Source_File));
1502
 
1503
         if Num_Source_Lines (Main_Source_File) = 1 then
1504
            Write_Str (" line: ");
1505
         else
1506
            Write_Str (" lines: ");
1507
         end if;
1508
 
1509
         if Total_Errors_Detected = 0 then
1510
            Write_Str ("No errors");
1511
 
1512
         elsif Total_Errors_Detected = 1 then
1513
            Write_Str ("1 error");
1514
 
1515
         else
1516
            Write_Int (Total_Errors_Detected);
1517
            Write_Str (" errors");
1518
         end if;
1519
 
1520
         if Warnings_Detected /= 0 then
1521
            Write_Str (", ");
1522
            Write_Int (Warnings_Detected);
1523
            Write_Str (" warning");
1524
 
1525
            if Warnings_Detected /= 1 then
1526
               Write_Char ('s');
1527
            end if;
1528
 
1529
            if Warning_Mode = Treat_As_Error then
1530
               Write_Str (" (treated as error");
1531
 
1532
               if Warnings_Detected /= 1 then
1533
                  Write_Char ('s');
1534
               end if;
1535
 
1536
               Write_Char (')');
1537
            end if;
1538
         end if;
1539
 
1540
         Write_Eol;
1541
         Set_Standard_Output;
1542
      end Write_Error_Summary;
1543
 
1544
      ------------------
1545
      -- Write_Header --
1546
      ------------------
1547
 
1548
      procedure Write_Header (Sfile : Source_File_Index) is
1549
      begin
1550
         if Verbose_Mode or Full_List then
1551
            if Original_Operating_Mode = Generate_Code then
1552
               Write_Str ("Compiling: ");
1553
            else
1554
               Write_Str ("Checking: ");
1555
            end if;
1556
 
1557
            Write_Name (Full_File_Name (Sfile));
1558
 
1559
            if not Debug_Flag_7 then
1560
               Write_Str (" (source file time stamp: ");
1561
               Write_Time_Stamp (Sfile);
1562
               Write_Char (')');
1563
            end if;
1564
 
1565
            Write_Eol;
1566
         end if;
1567
      end Write_Header;
1568
 
1569
      ----------------------
1570
      -- Write_Max_Errors --
1571
      ----------------------
1572
 
1573
      procedure Write_Max_Errors is
1574
      begin
1575
         if Maximum_Messages /= 0 then
1576
            if Warnings_Detected >= Maximum_Messages then
1577
               Set_Standard_Error;
1578
               Write_Line ("maximum number of warnings output");
1579
               Write_Line ("any further warnings suppressed");
1580
               Set_Standard_Output;
1581
            end if;
1582
 
1583
            --  If too many errors print message
1584
 
1585
            if Total_Errors_Detected >= Maximum_Messages then
1586
               Set_Standard_Error;
1587
               Write_Line ("fatal error: maximum number of errors detected");
1588
               Set_Standard_Output;
1589
            end if;
1590
         end if;
1591
      end Write_Max_Errors;
1592
 
1593
   --  Start of processing for Output_Messages
1594
 
1595
   begin
1596
      --  Error if Finalize has not been called
1597
 
1598
      if not Finalize_Called then
1599
         raise Program_Error;
1600
      end if;
1601
 
1602
      --  Reset current error source file if the main unit has a pragma
1603
      --  Source_Reference. This ensures outputting the proper name of
1604
      --  the source file in this situation.
1605
 
1606
      if Main_Source_File = No_Source_File
1607
        or else Num_SRef_Pragmas (Main_Source_File) /= 0
1608
      then
1609
         Current_Error_Source_File := No_Source_File;
1610
      end if;
1611
 
1612
      --  Brief Error mode
1613
 
1614
      if Brief_Output or (not Full_List and not Verbose_Mode) then
1615
         Set_Standard_Error;
1616
 
1617
         E := First_Error_Msg;
1618
         while E /= No_Error_Msg loop
1619
            if not Errors.Table (E).Deleted and then not Debug_Flag_KK then
1620
               if Full_Path_Name_For_Brief_Errors then
1621
                  Write_Name (Full_Ref_Name (Errors.Table (E).Sfile));
1622
               else
1623
                  Write_Name (Reference_Name (Errors.Table (E).Sfile));
1624
               end if;
1625
 
1626
               Write_Char (':');
1627
               Write_Int (Int (Physical_To_Logical
1628
                                (Errors.Table (E).Line,
1629
                                 Errors.Table (E).Sfile)));
1630
               Write_Char (':');
1631
 
1632
               if Errors.Table (E).Col < 10 then
1633
                  Write_Char ('0');
1634
               end if;
1635
 
1636
               Write_Int (Int (Errors.Table (E).Col));
1637
               Write_Str (": ");
1638
               Output_Msg_Text (E);
1639
               Write_Eol;
1640
            end if;
1641
 
1642
            E := Errors.Table (E).Next;
1643
         end loop;
1644
 
1645
         Set_Standard_Output;
1646
      end if;
1647
 
1648
      --  Full source listing case
1649
 
1650
      if Full_List then
1651
         List_Pragmas_Index := 1;
1652
         List_Pragmas_Mode := True;
1653
         E := First_Error_Msg;
1654
 
1655
         --  Normal case, to stdout (copyright notice already output)
1656
 
1657
         if Full_List_File_Name = null then
1658
            if not Debug_Flag_7 then
1659
               Write_Eol;
1660
            end if;
1661
 
1662
         --  Output to file
1663
 
1664
         else
1665
            Create_List_File_Access.all (Full_List_File_Name.all);
1666
            Set_Special_Output (Write_List_Info_Access.all'Access);
1667
 
1668
            --  Write copyright notice to file
1669
 
1670
            if not Debug_Flag_7 then
1671
               Write_Str ("GNAT ");
1672
               Write_Str (Gnat_Version_String);
1673
               Write_Eol;
1674
               Write_Str ("Copyright 1992-" &
1675
                          Current_Year &
1676
                          ", Free Software Foundation, Inc.");
1677
               Write_Eol;
1678
            end if;
1679
         end if;
1680
 
1681
         --  First list extended main source file units with errors
1682
 
1683
         for U in Main_Unit .. Last_Unit loop
1684
            if In_Extended_Main_Source_Unit (Cunit_Entity (U))
1685
 
1686
              --  If debug flag d.m is set, only the main source is listed
1687
 
1688
              and then (U = Main_Unit or else not Debug_Flag_Dot_M)
1689
 
1690
              --  If the unit of the entity does not come from source, it is
1691
              --  an implicit subprogram declaration for a child subprogram.
1692
              --  Do not emit errors for it, they are listed with the body.
1693
 
1694
              and then
1695
                (No (Cunit_Entity (U))
1696
                   or else Comes_From_Source (Cunit_Entity (U))
1697
                   or else not Is_Subprogram (Cunit_Entity (U)))
1698
            then
1699
               declare
1700
                  Sfile : constant Source_File_Index := Source_Index (U);
1701
 
1702
               begin
1703
                  Write_Eol;
1704
                  Write_Header (Sfile);
1705
                  Write_Eol;
1706
 
1707
                  --  Normally, we don't want an "error messages from file"
1708
                  --  message when listing the entire file, so we set the
1709
                  --  current source file as the current error source file.
1710
                  --  However, the old style of doing things was to list this
1711
                  --  message if pragma Source_Reference is present, even for
1712
                  --  the main unit. Since the purpose of the -gnatd.m switch
1713
                  --  is to duplicate the old behavior, we skip the reset if
1714
                  --  this debug flag is set.
1715
 
1716
                  if not Debug_Flag_Dot_M then
1717
                     Current_Error_Source_File := Sfile;
1718
                  end if;
1719
 
1720
                  for N in 1 .. Last_Source_Line (Sfile) loop
1721
                     while E /= No_Error_Msg
1722
                       and then Errors.Table (E).Deleted
1723
                     loop
1724
                        E := Errors.Table (E).Next;
1725
                     end loop;
1726
 
1727
                     Err_Flag :=
1728
                       E /= No_Error_Msg
1729
                         and then Errors.Table (E).Line = N
1730
                         and then Errors.Table (E).Sfile = Sfile;
1731
 
1732
                     Output_Source_Line (N, Sfile, Err_Flag);
1733
 
1734
                     if Err_Flag then
1735
                        Output_Error_Msgs (E);
1736
 
1737
                        if not Debug_Flag_2 then
1738
                           Write_Eol;
1739
                        end if;
1740
                     end if;
1741
                  end loop;
1742
               end;
1743
            end if;
1744
         end loop;
1745
 
1746
         --  Then output errors, if any, for subsidiary units not in the
1747
         --  main extended unit.
1748
 
1749
         --  Note: if debug flag d.m set, include errors for any units other
1750
         --  than the main unit in the extended source unit (e.g. spec and
1751
         --  subunits for a body).
1752
 
1753
         while E /= No_Error_Msg
1754
           and then (not In_Extended_Main_Source_Unit (Errors.Table (E).Sptr)
1755
                       or else
1756
                        (Debug_Flag_Dot_M
1757
                          and then Get_Source_Unit
1758
                                     (Errors.Table (E).Sptr) /= Main_Unit))
1759
         loop
1760
            if Errors.Table (E).Deleted then
1761
               E := Errors.Table (E).Next;
1762
 
1763
            else
1764
               Write_Eol;
1765
               Output_Source_Line
1766
                 (Errors.Table (E).Line, Errors.Table (E).Sfile, True);
1767
               Output_Error_Msgs (E);
1768
            end if;
1769
         end loop;
1770
 
1771
         --  If output to file, write extra copy of error summary to the
1772
         --  output file, and then close it.
1773
 
1774
         if Full_List_File_Name /= null then
1775
            Write_Error_Summary;
1776
            Write_Max_Errors;
1777
            Close_List_File_Access.all;
1778
            Cancel_Special_Output;
1779
         end if;
1780
      end if;
1781
 
1782
      --  Verbose mode (error lines only with error flags). Normally this is
1783
      --  ignored in full list mode, unless we are listing to a file, in which
1784
      --  case we still generate -gnatv output to standard output.
1785
 
1786
      if Verbose_Mode
1787
        and then (not Full_List or else Full_List_File_Name /= null)
1788
      then
1789
         Write_Eol;
1790
         Write_Header (Main_Source_File);
1791
         E := First_Error_Msg;
1792
 
1793
         --  Loop through error lines
1794
 
1795
         while E /= No_Error_Msg loop
1796
            if Errors.Table (E).Deleted then
1797
               E := Errors.Table (E).Next;
1798
            else
1799
               Write_Eol;
1800
               Output_Source_Line
1801
                 (Errors.Table (E).Line, Errors.Table (E).Sfile, True);
1802
               Output_Error_Msgs (E);
1803
            end if;
1804
         end loop;
1805
      end if;
1806
 
1807
      --  Output error summary if verbose or full list mode
1808
 
1809
      if Verbose_Mode or else Full_List then
1810
         Write_Error_Summary;
1811
      end if;
1812
 
1813
      Write_Max_Errors;
1814
 
1815
      if Warning_Mode = Treat_As_Error then
1816
         Total_Errors_Detected := Total_Errors_Detected + Warnings_Detected;
1817
         Warnings_Detected := 0;
1818
      end if;
1819
   end Output_Messages;
1820
 
1821
   ------------------------
1822
   -- Output_Source_Line --
1823
   ------------------------
1824
 
1825
   procedure Output_Source_Line
1826
     (L     : Physical_Line_Number;
1827
      Sfile : Source_File_Index;
1828
      Errs  : Boolean)
1829
   is
1830
      S : Source_Ptr;
1831
      C : Character;
1832
 
1833
      Line_Number_Output : Boolean := False;
1834
      --  Set True once line number is output
1835
 
1836
      Empty_Line : Boolean := True;
1837
      --  Set False if line includes at least one character
1838
 
1839
   begin
1840
      if Sfile /= Current_Error_Source_File then
1841
         Write_Str ("==============Error messages for ");
1842
 
1843
         case Sinput.File_Type (Sfile) is
1844
            when Sinput.Src =>
1845
               Write_Str ("source");
1846
 
1847
            when Sinput.Config =>
1848
               Write_Str ("configuration pragmas");
1849
 
1850
            when Sinput.Def =>
1851
               Write_Str ("symbol definition");
1852
 
1853
            when Sinput.Preproc =>
1854
               Write_Str ("preprocessing data");
1855
         end case;
1856
 
1857
         Write_Str (" file: ");
1858
         Write_Name (Full_File_Name (Sfile));
1859
         Write_Eol;
1860
 
1861
         if Num_SRef_Pragmas (Sfile) > 0 then
1862
            Write_Str ("--------------Line numbers from file: ");
1863
            Write_Name (Full_Ref_Name (Sfile));
1864
            Write_Str (" (starting at line ");
1865
            Write_Int (Int (First_Mapped_Line (Sfile)));
1866
            Write_Char (')');
1867
            Write_Eol;
1868
         end if;
1869
 
1870
         Current_Error_Source_File := Sfile;
1871
      end if;
1872
 
1873
      if Errs or List_Pragmas_Mode then
1874
         Output_Line_Number (Physical_To_Logical (L, Sfile));
1875
         Line_Number_Output := True;
1876
      end if;
1877
 
1878
      S := Line_Start (L, Sfile);
1879
 
1880
      loop
1881
         C := Source_Text (Sfile) (S);
1882
         exit when C = ASCII.LF or else C = ASCII.CR or else C = EOF;
1883
 
1884
         --  Deal with matching entry in List_Pragmas table
1885
 
1886
         if Full_List
1887
           and then List_Pragmas_Index <= List_Pragmas.Last
1888
           and then S = List_Pragmas.Table (List_Pragmas_Index).Ploc
1889
         then
1890
            case List_Pragmas.Table (List_Pragmas_Index).Ptyp is
1891
               when Page =>
1892
                  Write_Char (C);
1893
 
1894
                  --  Ignore if on line with errors so that error flags
1895
                  --  get properly listed with the error line .
1896
 
1897
                  if not Errs then
1898
                     Write_Char (ASCII.FF);
1899
                  end if;
1900
 
1901
               when List_On =>
1902
                  List_Pragmas_Mode := True;
1903
 
1904
                  if not Line_Number_Output then
1905
                     Output_Line_Number (Physical_To_Logical (L, Sfile));
1906
                     Line_Number_Output := True;
1907
                  end if;
1908
 
1909
                  Write_Char (C);
1910
 
1911
               when List_Off =>
1912
                  Write_Char (C);
1913
                  List_Pragmas_Mode := False;
1914
            end case;
1915
 
1916
            List_Pragmas_Index := List_Pragmas_Index + 1;
1917
 
1918
         --  Normal case (no matching entry in List_Pragmas table)
1919
 
1920
         else
1921
            if Errs or List_Pragmas_Mode then
1922
               Write_Char (C);
1923
            end if;
1924
         end if;
1925
 
1926
         Empty_Line := False;
1927
         S := S + 1;
1928
      end loop;
1929
 
1930
      --  If we have output a source line, then add the line terminator, with
1931
      --  training spaces preserved (so we output the line exactly as input).
1932
 
1933
      if Line_Number_Output then
1934
         if Empty_Line then
1935
            Write_Eol;
1936
         else
1937
            Write_Eol_Keep_Blanks;
1938
         end if;
1939
      end if;
1940
   end Output_Source_Line;
1941
 
1942
   -----------------------------
1943
   -- Remove_Warning_Messages --
1944
   -----------------------------
1945
 
1946
   procedure Remove_Warning_Messages (N : Node_Id) is
1947
 
1948
      function Check_For_Warning (N : Node_Id) return Traverse_Result;
1949
      --  This function checks one node for a possible warning message
1950
 
1951
      function Check_All_Warnings is new Traverse_Func (Check_For_Warning);
1952
      --  This defines the traversal operation
1953
 
1954
      -----------------------
1955
      -- Check_For_Warning --
1956
      -----------------------
1957
 
1958
      function Check_For_Warning (N : Node_Id) return Traverse_Result is
1959
         Loc : constant Source_Ptr := Sloc (N);
1960
         E   : Error_Msg_Id;
1961
 
1962
         function To_Be_Removed (E : Error_Msg_Id) return Boolean;
1963
         --  Returns True for a message that is to be removed. Also adjusts
1964
         --  warning count appropriately.
1965
 
1966
         -------------------
1967
         -- To_Be_Removed --
1968
         -------------------
1969
 
1970
         function To_Be_Removed (E : Error_Msg_Id) return Boolean is
1971
         begin
1972
            if E /= No_Error_Msg
1973
 
1974
               --  Don't remove if location does not match
1975
 
1976
               and then Errors.Table (E).Optr = Loc
1977
 
1978
               --  Don't remove if not warning/info message. Note that we do
1979
               --  not remove style messages here. They are warning messages
1980
               --  but not ones we want removed in this context.
1981
 
1982
               and then Errors.Table (E).Warn
1983
 
1984
               --  Don't remove unconditional messages
1985
 
1986
               and then not Errors.Table (E).Uncond
1987
            then
1988
               Warnings_Detected := Warnings_Detected - 1;
1989
               return True;
1990
 
1991
            --  No removal required
1992
 
1993
            else
1994
               return False;
1995
            end if;
1996
         end To_Be_Removed;
1997
 
1998
      --  Start of processing for Check_For_Warnings
1999
 
2000
      begin
2001
         while To_Be_Removed (First_Error_Msg) loop
2002
            First_Error_Msg := Errors.Table (First_Error_Msg).Next;
2003
         end loop;
2004
 
2005
         if First_Error_Msg = No_Error_Msg then
2006
            Last_Error_Msg := No_Error_Msg;
2007
         end if;
2008
 
2009
         E := First_Error_Msg;
2010
         while E /= No_Error_Msg loop
2011
            while To_Be_Removed (Errors.Table (E).Next) loop
2012
               Errors.Table (E).Next :=
2013
                 Errors.Table (Errors.Table (E).Next).Next;
2014
 
2015
               if Errors.Table (E).Next = No_Error_Msg then
2016
                  Last_Error_Msg := E;
2017
               end if;
2018
            end loop;
2019
 
2020
            E := Errors.Table (E).Next;
2021
         end loop;
2022
 
2023
         if Nkind (N) = N_Raise_Constraint_Error
2024
           and then Original_Node (N) /= N
2025
           and then No (Condition (N))
2026
         then
2027
            --  Warnings may have been posted on subexpressions of the original
2028
            --  tree. We place the original node back on the tree to remove
2029
            --  those warnings, whose sloc do not match those of any node in
2030
            --  the current tree. Given that we are in unreachable code, this
2031
            --  modification to the tree is harmless.
2032
 
2033
            declare
2034
               Status : Traverse_Final_Result;
2035
 
2036
            begin
2037
               if Is_List_Member (N) then
2038
                  Set_Condition (N, Original_Node (N));
2039
                  Status := Check_All_Warnings (Condition (N));
2040
               else
2041
                  Rewrite (N, Original_Node (N));
2042
                  Status := Check_All_Warnings (N);
2043
               end if;
2044
 
2045
               return Status;
2046
            end;
2047
 
2048
         else
2049
            return OK;
2050
         end if;
2051
      end Check_For_Warning;
2052
 
2053
   --  Start of processing for Remove_Warning_Messages
2054
 
2055
   begin
2056
      if Warnings_Detected /= 0 then
2057
         declare
2058
            Discard : Traverse_Final_Result;
2059
            pragma Warnings (Off, Discard);
2060
 
2061
         begin
2062
            Discard := Check_All_Warnings (N);
2063
         end;
2064
      end if;
2065
   end Remove_Warning_Messages;
2066
 
2067
   procedure Remove_Warning_Messages (L : List_Id) is
2068
      Stat : Node_Id;
2069
   begin
2070
      if Is_Non_Empty_List (L) then
2071
         Stat := First (L);
2072
         while Present (Stat) loop
2073
            Remove_Warning_Messages (Stat);
2074
            Next (Stat);
2075
         end loop;
2076
      end if;
2077
   end Remove_Warning_Messages;
2078
 
2079
   ---------------------------
2080
   -- Set_Identifier_Casing --
2081
   ---------------------------
2082
 
2083
   procedure Set_Identifier_Casing
2084
     (Identifier_Name : System.Address;
2085
      File_Name       : System.Address)
2086
   is
2087
      Ident : constant Big_String_Ptr := To_Big_String_Ptr (Identifier_Name);
2088
      File  : constant Big_String_Ptr := To_Big_String_Ptr (File_Name);
2089
      Flen  : Natural;
2090
 
2091
      Desired_Case : Casing_Type := Mixed_Case;
2092
      --  Casing required for result. Default value of Mixed_Case is used if
2093
      --  for some reason we cannot find the right file name in the table.
2094
 
2095
   begin
2096
      --  Get length of file name
2097
 
2098
      Flen := 0;
2099
      while File (Flen + 1) /= ASCII.NUL loop
2100
         Flen := Flen + 1;
2101
      end loop;
2102
 
2103
      --  Loop through file names to find matching one. This is a bit slow,
2104
      --  but we only do it in error situations so it is not so terrible.
2105
      --  Note that if the loop does not exit, then the desired case will
2106
      --  be left set to Mixed_Case, this can happen if the name was not
2107
      --  in canonical form, and gets canonicalized on VMS. Possibly we
2108
      --  could fix this by unconditinally canonicalizing these names ???
2109
 
2110
      for J in 1 .. Last_Source_File loop
2111
         Get_Name_String (Full_Debug_Name (J));
2112
 
2113
         if Name_Len = Flen
2114
           and then Name_Buffer (1 .. Name_Len) = String (File (1 .. Flen))
2115
         then
2116
            Desired_Case := Identifier_Casing (J);
2117
            exit;
2118
         end if;
2119
      end loop;
2120
 
2121
      --  Copy identifier as given to Name_Buffer
2122
 
2123
      for J in Name_Buffer'Range loop
2124
         Name_Buffer (J) := Ident (J);
2125
 
2126
         if Name_Buffer (J) = ASCII.NUL then
2127
            Name_Len := J - 1;
2128
            exit;
2129
         end if;
2130
      end loop;
2131
 
2132
      Set_Casing (Desired_Case);
2133
   end Set_Identifier_Casing;
2134
 
2135
   -----------------------
2136
   -- Set_Ignore_Errors --
2137
   -----------------------
2138
 
2139
   procedure Set_Ignore_Errors (To : Boolean) is
2140
   begin
2141
      Errors_Must_Be_Ignored := To;
2142
   end Set_Ignore_Errors;
2143
 
2144
   ------------------------------
2145
   -- Set_Msg_Insertion_Column --
2146
   ------------------------------
2147
 
2148
   procedure Set_Msg_Insertion_Column is
2149
   begin
2150
      if RM_Column_Check then
2151
         Set_Msg_Str (" in column ");
2152
         Set_Msg_Int (Int (Error_Msg_Col) + 1);
2153
      end if;
2154
   end Set_Msg_Insertion_Column;
2155
 
2156
   ----------------------------
2157
   -- Set_Msg_Insertion_Node --
2158
   ----------------------------
2159
 
2160
   procedure Set_Msg_Insertion_Node is
2161
      K : Node_Kind;
2162
 
2163
   begin
2164
      Suppress_Message :=
2165
        Error_Msg_Node_1 = Error
2166
          or else Error_Msg_Node_1 = Any_Type;
2167
 
2168
      if Error_Msg_Node_1 = Empty then
2169
         Set_Msg_Blank_Conditional;
2170
         Set_Msg_Str ("<empty>");
2171
 
2172
      elsif Error_Msg_Node_1 = Error then
2173
         Set_Msg_Blank;
2174
         Set_Msg_Str ("<error>");
2175
 
2176
      elsif Error_Msg_Node_1 = Standard_Void_Type then
2177
         Set_Msg_Blank;
2178
         Set_Msg_Str ("procedure name");
2179
 
2180
      else
2181
         Set_Msg_Blank_Conditional;
2182
 
2183
         --  Output name
2184
 
2185
         K := Nkind (Error_Msg_Node_1);
2186
 
2187
         --  If we have operator case, skip quotes since name of operator
2188
         --  itself will supply the required quotations. An operator can be
2189
         --  an applied use in an expression or an explicit operator symbol,
2190
         --  or an identifier whose name indicates it is an operator.
2191
 
2192
         if K in N_Op
2193
           or else K = N_Operator_Symbol
2194
           or else K = N_Defining_Operator_Symbol
2195
           or else ((K = N_Identifier or else K = N_Defining_Identifier)
2196
                       and then Is_Operator_Name (Chars (Error_Msg_Node_1)))
2197
         then
2198
            Set_Msg_Node (Error_Msg_Node_1);
2199
 
2200
         --  Normal case, not an operator, surround with quotes
2201
 
2202
         else
2203
            Set_Msg_Quote;
2204
            Set_Qualification (Error_Msg_Qual_Level, Error_Msg_Node_1);
2205
            Set_Msg_Node (Error_Msg_Node_1);
2206
            Set_Msg_Quote;
2207
         end if;
2208
      end if;
2209
 
2210
      --  The following assignment ensures that a second ampersand insertion
2211
      --  character will correspond to the Error_Msg_Node_2 parameter. We
2212
      --  suppress possible validity checks in case operating in -gnatVa mode,
2213
      --  and Error_Msg_Node_2 is not needed and has not been set.
2214
 
2215
      declare
2216
         pragma Suppress (Range_Check);
2217
      begin
2218
         Error_Msg_Node_1 := Error_Msg_Node_2;
2219
      end;
2220
   end Set_Msg_Insertion_Node;
2221
 
2222
   --------------------------------------
2223
   -- Set_Msg_Insertion_Type_Reference --
2224
   --------------------------------------
2225
 
2226
   procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr) is
2227
      Ent : Entity_Id;
2228
 
2229
   begin
2230
      Set_Msg_Blank;
2231
 
2232
      if Error_Msg_Node_1 = Standard_Void_Type then
2233
         Set_Msg_Str ("package or procedure name");
2234
         return;
2235
 
2236
      elsif Error_Msg_Node_1 = Standard_Exception_Type then
2237
         Set_Msg_Str ("exception name");
2238
         return;
2239
 
2240
      elsif     Error_Msg_Node_1 = Any_Access
2241
        or else Error_Msg_Node_1 = Any_Array
2242
        or else Error_Msg_Node_1 = Any_Boolean
2243
        or else Error_Msg_Node_1 = Any_Character
2244
        or else Error_Msg_Node_1 = Any_Composite
2245
        or else Error_Msg_Node_1 = Any_Discrete
2246
        or else Error_Msg_Node_1 = Any_Fixed
2247
        or else Error_Msg_Node_1 = Any_Integer
2248
        or else Error_Msg_Node_1 = Any_Modular
2249
        or else Error_Msg_Node_1 = Any_Numeric
2250
        or else Error_Msg_Node_1 = Any_Real
2251
        or else Error_Msg_Node_1 = Any_Scalar
2252
        or else Error_Msg_Node_1 = Any_String
2253
      then
2254
         Get_Unqualified_Decoded_Name_String (Chars (Error_Msg_Node_1));
2255
         Set_Msg_Name_Buffer;
2256
         return;
2257
 
2258
      elsif Error_Msg_Node_1 = Universal_Real then
2259
         Set_Msg_Str ("type universal real");
2260
         return;
2261
 
2262
      elsif Error_Msg_Node_1 = Universal_Integer then
2263
         Set_Msg_Str ("type universal integer");
2264
         return;
2265
 
2266
      elsif Error_Msg_Node_1 = Universal_Fixed then
2267
         Set_Msg_Str ("type universal fixed");
2268
         return;
2269
      end if;
2270
 
2271
      --  Special case of anonymous array
2272
 
2273
      if Nkind (Error_Msg_Node_1) in N_Entity
2274
        and then Is_Array_Type (Error_Msg_Node_1)
2275
        and then Present (Related_Array_Object (Error_Msg_Node_1))
2276
      then
2277
         Set_Msg_Str ("type of ");
2278
         Set_Msg_Node (Related_Array_Object (Error_Msg_Node_1));
2279
         Set_Msg_Str (" declared");
2280
         Set_Msg_Insertion_Line_Number
2281
           (Sloc (Related_Array_Object (Error_Msg_Node_1)), Flag);
2282
         return;
2283
      end if;
2284
 
2285
      --  If we fall through, it is not a special case, so first output
2286
      --  the name of the type, preceded by private for a private type
2287
 
2288
      if Is_Private_Type (Error_Msg_Node_1) then
2289
         Set_Msg_Str ("private type ");
2290
      else
2291
         Set_Msg_Str ("type ");
2292
      end if;
2293
 
2294
      Ent := Error_Msg_Node_1;
2295
 
2296
      if Is_Internal_Name (Chars (Ent)) then
2297
         Unwind_Internal_Type (Ent);
2298
      end if;
2299
 
2300
      --  Types in Standard are displayed as "Standard.name"
2301
 
2302
      if Sloc (Ent) <= Standard_Location then
2303
         Set_Msg_Quote;
2304
         Set_Msg_Str ("Standard.");
2305
         Set_Msg_Node (Ent);
2306
         Add_Class;
2307
         Set_Msg_Quote;
2308
 
2309
      --  Types in other language defined units are displayed as
2310
      --  "package-name.type-name"
2311
 
2312
      elsif
2313
        Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Ent)))
2314
      then
2315
         Get_Unqualified_Decoded_Name_String
2316
           (Unit_Name (Get_Source_Unit (Ent)));
2317
         Name_Len := Name_Len - 2;
2318
         Set_Msg_Quote;
2319
         Set_Casing (Mixed_Case);
2320
         Set_Msg_Name_Buffer;
2321
         Set_Msg_Char ('.');
2322
         Set_Casing (Mixed_Case);
2323
         Set_Msg_Node (Ent);
2324
         Add_Class;
2325
         Set_Msg_Quote;
2326
 
2327
      --  All other types display as "type name" defined at line xxx
2328
      --  possibly qualified if qualification is requested.
2329
 
2330
      else
2331
         Set_Msg_Quote;
2332
         Set_Qualification (Error_Msg_Qual_Level, Ent);
2333
         Set_Msg_Node (Ent);
2334
         Add_Class;
2335
 
2336
         --  If Ent is an anonymous subprogram type, there is no name
2337
         --  to print, so remove enclosing quotes.
2338
 
2339
         if Buffer_Ends_With ("""") then
2340
            Buffer_Remove ("""");
2341
         else
2342
            Set_Msg_Quote;
2343
         end if;
2344
      end if;
2345
 
2346
      --  If the original type did not come from a predefined
2347
      --  file, add the location where the type was defined.
2348
 
2349
      if Sloc (Error_Msg_Node_1) > Standard_Location
2350
        and then
2351
          not Is_Predefined_File_Name
2352
                (Unit_File_Name (Get_Source_Unit (Error_Msg_Node_1)))
2353
      then
2354
         Set_Msg_Str (" defined");
2355
         Set_Msg_Insertion_Line_Number (Sloc (Error_Msg_Node_1), Flag);
2356
 
2357
      --  If it did come from a predefined file, deal with the case where
2358
      --  this was a file with a generic instantiation from elsewhere.
2359
 
2360
      else
2361
         if Sloc (Error_Msg_Node_1) > Standard_Location then
2362
            declare
2363
               Iloc : constant Source_Ptr :=
2364
                        Instantiation_Location (Sloc (Error_Msg_Node_1));
2365
 
2366
            begin
2367
               if Iloc /= No_Location
2368
                 and then not Suppress_Instance_Location
2369
               then
2370
                  Set_Msg_Str (" from instance");
2371
                  Set_Msg_Insertion_Line_Number (Iloc, Flag);
2372
               end if;
2373
            end;
2374
         end if;
2375
      end if;
2376
   end Set_Msg_Insertion_Type_Reference;
2377
 
2378
   ---------------------------------
2379
   -- Set_Msg_Insertion_Unit_Name --
2380
   ---------------------------------
2381
 
2382
   procedure Set_Msg_Insertion_Unit_Name (Suffix : Boolean := True) is
2383
   begin
2384
      if Error_Msg_Unit_1 = No_Unit_Name then
2385
         null;
2386
 
2387
      elsif Error_Msg_Unit_1 = Error_Unit_Name then
2388
         Set_Msg_Blank;
2389
         Set_Msg_Str ("<error>");
2390
 
2391
      else
2392
         Get_Unit_Name_String (Error_Msg_Unit_1, Suffix);
2393
         Set_Msg_Blank;
2394
         Set_Msg_Quote;
2395
         Set_Msg_Name_Buffer;
2396
         Set_Msg_Quote;
2397
      end if;
2398
 
2399
      --  The following assignment ensures that a second percent insertion
2400
      --  character will correspond to the Error_Msg_Unit_2 parameter. We
2401
      --  suppress possible validity checks in case operating in -gnatVa mode,
2402
      --  and Error_Msg_Unit_2 is not needed and has not been set.
2403
 
2404
      declare
2405
         pragma Suppress (Range_Check);
2406
      begin
2407
         Error_Msg_Unit_1 := Error_Msg_Unit_2;
2408
      end;
2409
   end Set_Msg_Insertion_Unit_Name;
2410
 
2411
   ------------------
2412
   -- Set_Msg_Node --
2413
   ------------------
2414
 
2415
   procedure Set_Msg_Node (Node : Node_Id) is
2416
      Ent : Entity_Id;
2417
      Nam : Name_Id;
2418
 
2419
   begin
2420
      if Nkind (Node) = N_Designator then
2421
         Set_Msg_Node (Name (Node));
2422
         Set_Msg_Char ('.');
2423
         Set_Msg_Node (Identifier (Node));
2424
         return;
2425
 
2426
      elsif Nkind (Node) = N_Defining_Program_Unit_Name then
2427
         Set_Msg_Node (Name (Node));
2428
         Set_Msg_Char ('.');
2429
         Set_Msg_Node (Defining_Identifier (Node));
2430
         return;
2431
 
2432
      elsif Nkind (Node) = N_Selected_Component then
2433
         Set_Msg_Node (Prefix (Node));
2434
         Set_Msg_Char ('.');
2435
         Set_Msg_Node (Selector_Name (Node));
2436
         return;
2437
      end if;
2438
 
2439
      --  The only remaining possibilities are identifiers, defining
2440
      --  identifiers, pragmas, and pragma argument associations.
2441
 
2442
      if Nkind (Node) = N_Pragma then
2443
         Nam := Pragma_Name (Node);
2444
 
2445
      --  The other cases have Chars fields, and we want to test for possible
2446
      --  internal names, which generally represent something gone wrong. An
2447
      --  exception is the case of internal type names, where we try to find a
2448
      --  reasonable external representation for the external name
2449
 
2450
      elsif Is_Internal_Name (Chars (Node))
2451
        and then
2452
          ((Is_Entity_Name (Node)
2453
                          and then Present (Entity (Node))
2454
                          and then Is_Type (Entity (Node)))
2455
              or else
2456
           (Nkind (Node) = N_Defining_Identifier and then Is_Type (Node)))
2457
      then
2458
         if Nkind (Node) = N_Identifier then
2459
            Ent := Entity (Node);
2460
         else
2461
            Ent := Node;
2462
         end if;
2463
 
2464
         --  If the type is the designated type of an access_to_subprogram,
2465
         --  there is no name to provide in the call.
2466
 
2467
         if Ekind (Ent) = E_Subprogram_Type then
2468
            return;
2469
         else
2470
            Unwind_Internal_Type (Ent);
2471
            Nam := Chars (Ent);
2472
         end if;
2473
 
2474
      --  If not internal name, just use name in Chars field
2475
 
2476
      else
2477
         Nam := Chars (Node);
2478
      end if;
2479
 
2480
      --  At this stage, the name to output is in Nam
2481
 
2482
      Get_Unqualified_Decoded_Name_String (Nam);
2483
 
2484
      --  Remove trailing upper case letters from the name (useful for
2485
      --  dealing with some cases of internal names.
2486
 
2487
      while Name_Len > 1 and then Name_Buffer (Name_Len) in 'A' .. 'Z' loop
2488
         Name_Len := Name_Len  - 1;
2489
      end loop;
2490
 
2491
      --  If we have any of the names from standard that start with the
2492
      --  characters "any " (e.g. Any_Type), then kill the message since
2493
      --  almost certainly it is a junk cascaded message.
2494
 
2495
      if Name_Len > 4
2496
        and then Name_Buffer (1 .. 4) = "any "
2497
      then
2498
         Kill_Message := True;
2499
      end if;
2500
 
2501
      --  Now we have to set the proper case. If we have a source location
2502
      --  then do a check to see if the name in the source is the same name
2503
      --  as the name in the Names table, except for possible differences
2504
      --  in case, which is the case when we can copy from the source.
2505
 
2506
      declare
2507
         Src_Loc : constant Source_Ptr := Sloc (Error_Msg_Node_1);
2508
         Sbuffer : Source_Buffer_Ptr;
2509
         Ref_Ptr : Integer;
2510
         Src_Ptr : Source_Ptr;
2511
 
2512
      begin
2513
         Ref_Ptr := 1;
2514
         Src_Ptr := Src_Loc;
2515
 
2516
         --  For standard locations, always use mixed case
2517
 
2518
         if Src_Loc <= No_Location
2519
           or else Sloc (Node) <= No_Location
2520
         then
2521
            Set_Casing (Mixed_Case);
2522
 
2523
         else
2524
            --  Determine if the reference we are dealing with corresponds
2525
            --  to text at the point of the error reference. This will often
2526
            --  be the case for simple identifier references, and is the case
2527
            --  where we can copy the spelling from the source.
2528
 
2529
            Sbuffer := Source_Text (Get_Source_File_Index (Src_Loc));
2530
 
2531
            while Ref_Ptr <= Name_Len loop
2532
               exit when
2533
                 Fold_Lower (Sbuffer (Src_Ptr)) /=
2534
                 Fold_Lower (Name_Buffer (Ref_Ptr));
2535
               Ref_Ptr := Ref_Ptr + 1;
2536
               Src_Ptr := Src_Ptr + 1;
2537
            end loop;
2538
 
2539
            --  If we get through the loop without a mismatch, then output
2540
            --  the name the way it is spelled in the source program
2541
 
2542
            if Ref_Ptr > Name_Len then
2543
               Src_Ptr := Src_Loc;
2544
 
2545
               for J in 1 .. Name_Len loop
2546
                  Name_Buffer (J) := Sbuffer (Src_Ptr);
2547
                  Src_Ptr := Src_Ptr + 1;
2548
               end loop;
2549
 
2550
            --  Otherwise set the casing using the default identifier casing
2551
 
2552
            else
2553
               Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case);
2554
            end if;
2555
         end if;
2556
      end;
2557
 
2558
      Set_Msg_Name_Buffer;
2559
      Add_Class;
2560
   end Set_Msg_Node;
2561
 
2562
   ------------------
2563
   -- Set_Msg_Text --
2564
   ------------------
2565
 
2566
   procedure Set_Msg_Text (Text : String; Flag : Source_Ptr) is
2567
      C : Character;   -- Current character
2568
      P : Natural;     -- Current index;
2569
 
2570
   begin
2571
      Manual_Quote_Mode := False;
2572
      Is_Unconditional_Msg := False;
2573
      Msglen := 0;
2574
      Flag_Source := Get_Source_File_Index (Flag);
2575
      P := Text'First;
2576
 
2577
      while P <= Text'Last loop
2578
         C := Text (P);
2579
         P := P + 1;
2580
 
2581
         --  Check for insertion character or sequence
2582
 
2583
         case C is
2584
            when '%' =>
2585
               if P <= Text'Last and then Text (P) = '%' then
2586
                  P := P + 1;
2587
                  Set_Msg_Insertion_Name_Literal;
2588
               else
2589
                  Set_Msg_Insertion_Name;
2590
               end if;
2591
 
2592
            when '$' =>
2593
               if P <= Text'Last and then Text (P) = '$' then
2594
                  P := P + 1;
2595
                  Set_Msg_Insertion_Unit_Name (Suffix => False);
2596
 
2597
               else
2598
                  Set_Msg_Insertion_Unit_Name;
2599
               end if;
2600
 
2601
            when '{' =>
2602
               Set_Msg_Insertion_File_Name;
2603
 
2604
            when '}' =>
2605
               Set_Msg_Insertion_Type_Reference (Flag);
2606
 
2607
            when '*' =>
2608
               Set_Msg_Insertion_Reserved_Name;
2609
 
2610
            when '&' =>
2611
               Set_Msg_Insertion_Node;
2612
 
2613
            when '#' =>
2614
               Set_Msg_Insertion_Line_Number (Error_Msg_Sloc, Flag);
2615
 
2616
            when '\' =>
2617
               Continuation := True;
2618
 
2619
               if Text (P) = '\' then
2620
                  Continuation_New_Line := True;
2621
                  P := P + 1;
2622
               end if;
2623
 
2624
            when '@' =>
2625
               Set_Msg_Insertion_Column;
2626
 
2627
            when '>' =>
2628
               Set_Msg_Insertion_Run_Time_Name;
2629
 
2630
            when '^' =>
2631
               Set_Msg_Insertion_Uint;
2632
 
2633
            when '`' =>
2634
               Manual_Quote_Mode := not Manual_Quote_Mode;
2635
               Set_Msg_Char ('"');
2636
 
2637
            when '!' =>
2638
               Is_Unconditional_Msg := True;
2639
 
2640
            when '?' =>
2641
               null; -- already dealt with
2642
 
2643
            when '<' =>
2644
               null; -- already dealt with
2645
 
2646
            when '|' =>
2647
               null; -- already dealt with
2648
 
2649
            when ''' =>
2650
               Set_Msg_Char (Text (P));
2651
               P := P + 1;
2652
 
2653
            when '~' =>
2654
               Set_Msg_Str (Error_Msg_String (1 .. Error_Msg_Strlen));
2655
 
2656
            --  Upper case letter
2657
 
2658
            when 'A' .. 'Z' =>
2659
 
2660
               --  Start of reserved word if two or more
2661
 
2662
               if P <= Text'Last and then Text (P) in 'A' .. 'Z' then
2663
                  P := P - 1;
2664
                  Set_Msg_Insertion_Reserved_Word (Text, P);
2665
 
2666
               --  Single upper case letter is just inserted
2667
 
2668
               else
2669
                  Set_Msg_Char (C);
2670
               end if;
2671
 
2672
            --  Normal character with no special treatment
2673
 
2674
            when others =>
2675
               Set_Msg_Char (C);
2676
         end case;
2677
      end loop;
2678
 
2679
      VMS_Convert;
2680
   end Set_Msg_Text;
2681
 
2682
   ----------------
2683
   -- Set_Posted --
2684
   ----------------
2685
 
2686
   procedure Set_Posted (N : Node_Id) is
2687
      P : Node_Id;
2688
 
2689
   begin
2690
      if Is_Serious_Error then
2691
 
2692
         --  We always set Error_Posted on the node itself
2693
 
2694
         Set_Error_Posted (N);
2695
 
2696
         --  If it is a subexpression, then set Error_Posted on parents up to
2697
         --  and including the first non-subexpression construct. This helps
2698
         --  avoid cascaded error messages within a single expression.
2699
 
2700
         P := N;
2701
         loop
2702
            P := Parent (P);
2703
            exit when No (P);
2704
            Set_Error_Posted (P);
2705
            exit when Nkind (P) not in N_Subexpr;
2706
         end loop;
2707
 
2708
         --  A special check, if we just posted an error on an attribute
2709
         --  definition clause, then also set the entity involved as posted.
2710
         --  For example, this stops complaining about the alignment after
2711
         --  complaining about the size, which is likely to be useless.
2712
 
2713
         if Nkind (P) = N_Attribute_Definition_Clause then
2714
            if Is_Entity_Name (Name (P)) then
2715
               Set_Error_Posted (Entity (Name (P)));
2716
            end if;
2717
         end if;
2718
      end if;
2719
   end Set_Posted;
2720
 
2721
   -----------------------
2722
   -- Set_Qualification --
2723
   -----------------------
2724
 
2725
   procedure Set_Qualification (N : Nat; E : Entity_Id) is
2726
   begin
2727
      if N /= 0 and then Scope (E) /= Standard_Standard then
2728
         Set_Qualification (N - 1, Scope (E));
2729
         Set_Msg_Node (Scope (E));
2730
         Set_Msg_Char ('.');
2731
      end if;
2732
   end Set_Qualification;
2733
 
2734
   ------------------------
2735
   -- Special_Msg_Delete --
2736
   ------------------------
2737
 
2738
   --  Is it really right to have all this specialized knowledge in errout?
2739
 
2740
   function Special_Msg_Delete
2741
     (Msg : String;
2742
      N   : Node_Or_Entity_Id;
2743
      E   : Node_Or_Entity_Id) return Boolean
2744
   is
2745
   begin
2746
      --  Never delete messages in -gnatdO mode
2747
 
2748
      if Debug_Flag_OO then
2749
         return False;
2750
 
2751
      --  Processing for "atomic access cannot be guaranteed"
2752
 
2753
      elsif Msg = "atomic access to & cannot be guaranteed" then
2754
 
2755
         --  When an atomic object refers to a non-atomic type in the same
2756
         --  scope, we implicitly make the type atomic. In the non-error case
2757
         --  this is surely safe (and in fact prevents an error from occurring
2758
         --  if the type is not atomic by default). But if the object cannot be
2759
         --  made atomic, then we introduce an extra junk message by this
2760
         --  manipulation, which we get rid of here.
2761
 
2762
         --  We identify this case by the fact that it references a type for
2763
         --  which Is_Atomic is set, but there is no Atomic pragma setting it.
2764
 
2765
         if Is_Type (E)
2766
           and then Is_Atomic (E)
2767
           and then No (Get_Rep_Pragma (E, Name_Atomic))
2768
         then
2769
            return True;
2770
         end if;
2771
 
2772
      --  Processing for "Size too small" messages
2773
 
2774
      elsif Msg = "size for& too small, minimum allowed is ^" then
2775
 
2776
         --  Suppress "size too small" errors in CodePeer mode, since pragma
2777
         --  Pack is also ignored in this configuration.
2778
 
2779
         if CodePeer_Mode then
2780
            return True;
2781
 
2782
         --  When a size is wrong for a frozen type there is no explicit size
2783
         --  clause, and other errors have occurred, suppress the message,
2784
         --  since it is likely that this size error is a cascaded result of
2785
         --  other errors. The reason we eliminate unfrozen types is that
2786
         --  messages issued before the freeze type are for sure OK.
2787
 
2788
         elsif Is_Frozen (E)
2789
           and then Serious_Errors_Detected > 0
2790
           and then Nkind (N) /= N_Component_Clause
2791
           and then Nkind (Parent (N)) /= N_Component_Clause
2792
           and then
2793
             No (Get_Attribute_Definition_Clause (E, Attribute_Size))
2794
           and then
2795
             No (Get_Attribute_Definition_Clause (E, Attribute_Object_Size))
2796
           and then
2797
             No (Get_Attribute_Definition_Clause (E, Attribute_Value_Size))
2798
         then
2799
            return True;
2800
         end if;
2801
      end if;
2802
 
2803
      --  All special tests complete, so go ahead with message
2804
 
2805
      return False;
2806
   end Special_Msg_Delete;
2807
 
2808
   --------------------------
2809
   -- Unwind_Internal_Type --
2810
   --------------------------
2811
 
2812
   procedure Unwind_Internal_Type (Ent : in out Entity_Id) is
2813
      Derived : Boolean := False;
2814
      Mchar   : Character;
2815
      Old_Ent : Entity_Id;
2816
 
2817
   begin
2818
      --  Undo placement of a quote, since we will put it back later
2819
 
2820
      Mchar := Msg_Buffer (Msglen);
2821
 
2822
      if Mchar = '"' then
2823
         Msglen := Msglen - 1;
2824
      end if;
2825
 
2826
      --  The loop here deals with recursive types, we are trying to find a
2827
      --  related entity that is not an implicit type. Note that the check with
2828
      --  Old_Ent stops us from getting "stuck". Also, we don't output the
2829
      --  "type derived from" message more than once in the case where we climb
2830
      --  up multiple levels.
2831
 
2832
      loop
2833
         Old_Ent := Ent;
2834
 
2835
         --  Implicit access type, use directly designated type In Ada 2005,
2836
         --  the designated type may be an anonymous access to subprogram, in
2837
         --  which case we can only point to its definition.
2838
 
2839
         if Is_Access_Type (Ent) then
2840
            if Ekind (Ent) = E_Access_Subprogram_Type
2841
              or else Ekind (Ent) = E_Anonymous_Access_Subprogram_Type
2842
              or else Is_Access_Protected_Subprogram_Type (Ent)
2843
            then
2844
               Ent := Directly_Designated_Type (Ent);
2845
 
2846
               if not Comes_From_Source (Ent) then
2847
                  if Buffer_Ends_With ("type ") then
2848
                     Buffer_Remove ("type ");
2849
                  end if;
2850
 
2851
                  if Is_Itype (Ent) then
2852
                     declare
2853
                        Assoc : constant Node_Id :=
2854
                                  Associated_Node_For_Itype (Ent);
2855
 
2856
                     begin
2857
                        if Nkind (Assoc) in N_Subprogram_Specification then
2858
 
2859
                           --  Anonymous access to subprogram in a signature.
2860
                           --  Indicate the enclosing subprogram.
2861
 
2862
                           Ent :=
2863
                             Defining_Unit_Name
2864
                               (Associated_Node_For_Itype (Ent));
2865
                           Set_Msg_Str
2866
                             ("access to subprogram declared in profile of ");
2867
 
2868
                        else
2869
                           Set_Msg_Str ("access to subprogram with profile ");
2870
                        end if;
2871
                     end;
2872
                  end if;
2873
 
2874
               elsif Ekind (Ent) = E_Function then
2875
                  Set_Msg_Str ("access to function ");
2876
               else
2877
                  Set_Msg_Str ("access to procedure ");
2878
               end if;
2879
 
2880
               exit;
2881
 
2882
            --  Type is access to object, named or anonymous
2883
 
2884
            else
2885
               Set_Msg_Str ("access to ");
2886
               Ent := Directly_Designated_Type (Ent);
2887
            end if;
2888
 
2889
         --  Classwide type
2890
 
2891
         elsif Is_Class_Wide_Type (Ent) then
2892
            Class_Flag := True;
2893
            Ent := Root_Type (Ent);
2894
 
2895
         --  Use base type if this is a subtype
2896
 
2897
         elsif Ent /= Base_Type (Ent) then
2898
            Buffer_Remove ("type ");
2899
 
2900
            --  Avoid duplication "subtype of subtype of", and also replace
2901
            --  "derived from subtype of" simply by "derived from"
2902
 
2903
            if not Buffer_Ends_With ("subtype of ")
2904
              and then not Buffer_Ends_With ("derived from ")
2905
            then
2906
               Set_Msg_Str ("subtype of ");
2907
            end if;
2908
 
2909
            Ent := Base_Type (Ent);
2910
 
2911
         --  If this is a base type with a first named subtype, use the first
2912
         --  named subtype instead. This is not quite accurate in all cases,
2913
         --  but it makes too much noise to be accurate and add 'Base in all
2914
         --  cases. Note that we only do this is the first named subtype is not
2915
         --  itself an internal name. This avoids the obvious loop (subtype ->
2916
         --  basetype -> subtype) which would otherwise occur!)
2917
 
2918
         elsif Present (Freeze_Node (Ent))
2919
           and then Present (First_Subtype_Link (Freeze_Node (Ent)))
2920
           and then
2921
             not Is_Internal_Name
2922
                   (Chars (First_Subtype_Link (Freeze_Node (Ent))))
2923
         then
2924
            Ent := First_Subtype_Link (Freeze_Node (Ent));
2925
 
2926
         --  Otherwise use root type
2927
 
2928
         else
2929
            if not Derived then
2930
               Buffer_Remove ("type ");
2931
 
2932
               --  Test for "subtype of type derived from" which seems
2933
               --  excessive and is replaced by simply "type derived from"
2934
 
2935
               Buffer_Remove ("subtype of");
2936
 
2937
               --  Avoid duplication "type derived from type derived from"
2938
 
2939
               if not Buffer_Ends_With ("type derived from ") then
2940
                  Set_Msg_Str ("type derived from ");
2941
               end if;
2942
 
2943
               Derived := True;
2944
            end if;
2945
 
2946
            Ent := Etype (Ent);
2947
         end if;
2948
 
2949
         --  If we are stuck in a loop, get out and settle for the internal
2950
         --  name after all. In this case we set to kill the message if it
2951
         --  is not the first error message (we really try hard not to show
2952
         --  the dirty laundry of the implementation to the poor user!)
2953
 
2954
         if Ent = Old_Ent then
2955
            Kill_Message := True;
2956
            exit;
2957
         end if;
2958
 
2959
         --  Get out if we finally found a non-internal name to use
2960
 
2961
         exit when not Is_Internal_Name (Chars (Ent));
2962
      end loop;
2963
 
2964
      if Mchar = '"' then
2965
         Set_Msg_Char ('"');
2966
      end if;
2967
   end Unwind_Internal_Type;
2968
 
2969
   -----------------
2970
   -- VMS_Convert --
2971
   -----------------
2972
 
2973
   procedure VMS_Convert is
2974
      P : Natural;
2975
      L : Natural;
2976
      N : Natural;
2977
 
2978
   begin
2979
      if not OpenVMS then
2980
         return;
2981
      end if;
2982
 
2983
      P := Msg_Buffer'First;
2984
      loop
2985
         if P >= Msglen then
2986
            return;
2987
         end if;
2988
 
2989
         if Msg_Buffer (P) = '-' then
2990
            for G in Gnames'Range loop
2991
               L := Gnames (G)'Length;
2992
 
2993
               --  See if we have "-ggg switch", where ggg is Gnames entry
2994
 
2995
               if P + L + 7 <= Msglen
2996
                 and then Msg_Buffer (P + 1 .. P + L) = Gnames (G).all
2997
                 and then Msg_Buffer (P + L + 1 .. P + L + 7) = " switch"
2998
               then
2999
                  --  Replace by "/vvv qualifier", where vvv is Vnames entry
3000
 
3001
                  N := Vnames (G)'Length;
3002
                  Msg_Buffer (P + N + 11 .. Msglen + N - L + 3) :=
3003
                    Msg_Buffer (P + L + 8 .. Msglen);
3004
                  Msg_Buffer (P) := '/';
3005
                  Msg_Buffer (P + 1 .. P + N) := Vnames (G).all;
3006
                  Msg_Buffer (P + N + 1 .. P + N + 10) := " qualifier";
3007
                  P := P + N + 10;
3008
                  Msglen := Msglen + N - L + 3;
3009
                  exit;
3010
               end if;
3011
            end loop;
3012
         end if;
3013
 
3014
         P := P + 1;
3015
      end loop;
3016
   end VMS_Convert;
3017
 
3018
end Errout;

powered by: WebSVN 2.1.0

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