* dwarf2out.c (loc_descriptor_from_tree, case CONSTRUCTOR): New case.
[official-gcc.git] / gcc / ada / errout.adb
blob7935a63473ff80ad1a5347f8d85b47a9da1188a4
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E R R O U T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 -- Warning! Error messages can be generated during Gigi processing by direct
28 -- calls to error message routines, so it is essential that the processing
29 -- in this body be consistent with the requirements for the Gigi processing
30 -- environment, and that in particular, no disallowed table expansion is
31 -- allowed to occur.
33 with Atree; use Atree;
34 with Casing; use Casing;
35 with Csets; use Csets;
36 with Debug; use Debug;
37 with Einfo; use Einfo;
38 with Fname; use Fname;
39 with Hostparm;
40 with Lib; use Lib;
41 with Namet; use Namet;
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 Style;
51 with Uintp; use Uintp;
52 with Uname; use Uname;
54 package body Errout is
56 Class_Flag : Boolean := False;
57 -- This flag is set True when outputting a reference to a class-wide
58 -- type, and is used by Add_Class to insert 'Class at the proper point
60 Continuation : Boolean;
61 -- Indicates if current message is a continuation. Initialized from the
62 -- Msg_Cont parameter in Error_Msg_Internal and then set True if a \
63 -- insertion character is encountered.
65 Cur_Msg : Error_Msg_Id;
66 -- Id of most recently posted error message
68 Flag_Source : Source_File_Index;
69 -- Source file index for source file where error is being posted
71 Is_Warning_Msg : Boolean;
72 -- Set by Set_Msg_Text to indicate if current message is warning message
74 Is_Serious_Error : Boolean;
75 -- Set by Set_Msg_Text to indicate if current message is serious error
77 Is_Unconditional_Msg : Boolean;
78 -- Set by Set_Msg_Text to indicate if current message is unconditional
80 Kill_Message : Boolean;
81 -- A flag used to kill weird messages (e.g. those containing uninterpreted
82 -- implicit type references) if we have already seen at least one message
83 -- already. The idea is that we hope the weird message is a junk cascaded
84 -- message that should be suppressed.
86 Last_Killed : Boolean := False;
87 -- Set True if the most recently posted non-continuation message was
88 -- killed. This is used to determine the processing of any continuation
89 -- messages that follow.
91 List_Pragmas_Index : Int;
92 -- Index into List_Pragmas table
94 List_Pragmas_Mode : Boolean;
95 -- Starts True, gets set False by pragma List (Off), True by List (On)
97 Manual_Quote_Mode : Boolean;
98 -- Set True in manual quotation mode
100 Max_Msg_Length : constant := 80 + 2 * Hostparm.Max_Line_Length;
101 -- Maximum length of error message. The addition of Max_Line_Length
102 -- ensures that two insertion tokens of maximum length can be accomodated.
104 Msg_Buffer : String (1 .. Max_Msg_Length);
105 -- Buffer used to prepare error messages
107 Msglen : Integer;
108 -- Number of characters currently stored in the message buffer
110 Suppress_Message : Boolean;
111 -- A flag used to suppress certain obviously redundant messages (i.e.
112 -- those referring to a node whose type is Any_Type). This suppression
113 -- is effective only if All_Errors_Mode is off.
115 Suppress_Instance_Location : Boolean := False;
116 -- Normally, if a # location in a message references a location within
117 -- a generic template, then a note is added giving the location of the
118 -- instantiation. If this variable is set True, then this note is not
119 -- output. This is used for internal processing for the case of an
120 -- illegal instantiation. See Error_Msg routine for further details.
122 -----------------------------------
123 -- Error Message Data Structures --
124 -----------------------------------
126 -- The error messages are stored as a linked list of error message objects
127 -- sorted into ascending order by the source location (Sloc). Each object
128 -- records the text of the message and its source location.
130 -- The following record type and table are used to represent error
131 -- messages, with one entry in the table being allocated for each message.
133 type Error_Msg_Object is record
134 Text : String_Ptr;
135 -- Text of error message, fully expanded with all insertions
137 Next : Error_Msg_Id;
138 -- Pointer to next message in error chain
140 Sfile : Source_File_Index;
141 -- Source table index of source file. In the case of an error that
142 -- refers to a template, always references the original template
143 -- not an instantiation copy.
145 Sptr : Source_Ptr;
146 -- Flag pointer. In the case of an error that refers to a template,
147 -- always references the original template, not an instantiation copy.
148 -- This value is the actual place in the source that the error message
149 -- will be posted.
151 Fptr : Source_Ptr;
152 -- Flag location used in the call to post the error. This is normally
153 -- the same as Sptr, except in the case of instantiations, where it
154 -- is the original flag location value. This may refer to an instance
155 -- when the actual message (and hence Sptr) references the template.
157 Line : Physical_Line_Number;
158 -- Line number for error message
160 Col : Column_Number;
161 -- Column number for error message
163 Warn : Boolean;
164 -- True if warning message (i.e. insertion character ? appeared)
166 Serious : Boolean;
167 -- True if serious error message (not a warning and no | character)
169 Uncond : Boolean;
170 -- True if unconditional message (i.e. insertion character ! appeared)
172 Msg_Cont : Boolean;
173 -- This is used for logical messages that are composed of multiple
174 -- individual messages. For messages that are not part of such a
175 -- group, or that are the first message in such a group. Msg_Cont
176 -- is set to False. For subsequent messages in a group, Msg_Cont
177 -- is set to True. This is used to make sure that such a group of
178 -- messages is either suppressed or retained as a group (e.g. in
179 -- the circuit that deletes identical messages).
181 Deleted : Boolean;
182 -- If this flag is set, the message is not printed. This is used
183 -- in the circuit for deleting duplicate/redundant error messages.
184 end record;
186 package Errors is new Table.Table (
187 Table_Component_Type => Error_Msg_Object,
188 Table_Index_Type => Error_Msg_Id,
189 Table_Low_Bound => 1,
190 Table_Initial => 200,
191 Table_Increment => 200,
192 Table_Name => "Error");
194 Error_Msgs : Error_Msg_Id;
195 -- The list of error messages
197 --------------------------
198 -- Warning Mode Control --
199 --------------------------
201 -- Pragma Warnings allows warnings to be turned off for a specified
202 -- region of code, and the following tabl is the data structure used
203 -- to keep track of these regions.
205 -- It contains pairs of source locations, the first being the start
206 -- location for a warnings off region, and the second being the end
207 -- location. When a pragma Warnings (Off) is encountered, a new entry
208 -- is established extending from the location of the pragma to the
209 -- end of the current source file. A subsequent pragma Warnings (On)
210 -- adjusts the end point of this entry appropriately.
212 -- If all warnings are suppressed by comamnd switch, then there is a
213 -- dummy entry (put there by Errout.Initialize) at the start of the
214 -- table which covers all possible Source_Ptr values. Note that the
215 -- source pointer values in this table always reference the original
216 -- template, not an instantiation copy, in the generic case.
218 type Warnings_Entry is record
219 Start : Source_Ptr;
220 Stop : Source_Ptr;
221 end record;
223 package Warnings is new Table.Table (
224 Table_Component_Type => Warnings_Entry,
225 Table_Index_Type => Natural,
226 Table_Low_Bound => 1,
227 Table_Initial => 100,
228 Table_Increment => 200,
229 Table_Name => "Warnings");
231 -----------------------
232 -- Local Subprograms --
233 -----------------------
235 procedure Add_Class;
236 -- Add 'Class to buffer for class wide type case (Class_Flag set)
238 function Buffer_Ends_With (S : String) return Boolean;
239 -- Tests if message buffer ends with given string preceded by a space
241 procedure Buffer_Remove (S : String);
242 -- Removes given string from end of buffer if it is present
243 -- at end of buffer, and preceded by a space.
245 procedure Debug_Output (N : Node_Id);
246 -- Called from Error_Msg_N and Error_Msg_NE to generate line of debug
247 -- output giving node number (of node N) if the debug X switch is set.
249 procedure Check_Duplicate_Message (M1, M2 : Error_Msg_Id);
250 -- This function is passed the Id values of two error messages. If
251 -- either M1 or M2 is a continuation message, or is already deleted,
252 -- the call is ignored. Otherwise a check is made to see if M1 and M2
253 -- are duplicated or redundant. If so, the message to be deleted and
254 -- all its continuations are marked with the Deleted flag set to True.
256 procedure Error_Msg_Internal
257 (Msg : String;
258 Flag_Location : Source_Ptr;
259 Msg_Cont : Boolean);
260 -- This is like Error_Msg, except that Flag_Location is known not to be
261 -- a location within a instantiation of a generic template. The outer
262 -- level routine, Error_Msg, takes care of dealing with the generic case.
263 -- Msg_Cont is set True to indicate that the message is a continuation of
264 -- a previous message. This means that it must have the same Flag_Location
265 -- as the previous message.
267 procedure Set_Next_Non_Deleted_Msg (E : in out Error_Msg_Id);
268 -- Given a message id, move to next message id, but skip any deleted
269 -- messages, so that this results in E on output being the first non-
270 -- deleted message following the input value of E, or No_Error_Msg if
271 -- the input value of E was either already No_Error_Msg, or was the
272 -- last non-deleted message.
274 function No_Warnings (N : Node_Or_Entity_Id) return Boolean;
275 -- Determines if warnings should be suppressed for the given node
277 function OK_Node (N : Node_Id) return Boolean;
278 -- Determines if a node is an OK node to place an error message on (return
279 -- True) or if the error message should be suppressed (return False). A
280 -- message is suppressed if the node already has an error posted on it,
281 -- or if it refers to an Etype that has an error posted on it, or if
282 -- it references an Entity that has an error posted on it.
284 procedure Output_Error_Msgs (E : in out Error_Msg_Id);
285 -- Output source line, error flag, and text of stored error message and
286 -- all subsequent messages for the same line and unit. On return E is
287 -- set to be one higher than the last message output.
289 procedure Output_Line_Number (L : Logical_Line_Number);
290 -- Output a line number as six digits (with leading zeroes suppressed),
291 -- followed by a period and a blank (note that this is 8 characters which
292 -- means that tabs in the source line will not get messed up). Line numbers
293 -- that match or are less than the last Source_Reference pragma are listed
294 -- as all blanks, avoiding output of junk line numbers.
296 procedure Output_Msg_Text (E : Error_Msg_Id);
297 -- Outputs characters of text in the text of the error message E, excluding
298 -- any final exclamation point. Note that no end of line is output, the
299 -- caller is responsible for adding the end of line.
301 procedure Output_Source_Line
302 (L : Physical_Line_Number;
303 Sfile : Source_File_Index;
304 Errs : Boolean);
305 -- Outputs text of source line L, in file S, together with preceding line
306 -- number, as described above for Output_Line_Number. The Errs parameter
307 -- indicates if there are errors attached to the line, which forces
308 -- listing on, even in the presence of pragma List (Off).
310 function Same_Error (M1, M2 : Error_Msg_Id) return Boolean;
311 -- See if two messages have the same text. Returns true if the text
312 -- of the two messages is identical, or if one of them is the same
313 -- as the other with an appended "instance at xxx" tag.
315 procedure Set_Msg_Blank;
316 -- Sets a single blank in the message if the preceding character is a
317 -- non-blank character other than a left parenthesis. Has no effect if
318 -- manual quote mode is turned on.
320 procedure Set_Msg_Blank_Conditional;
321 -- Sets a single blank in the message if the preceding character is a
322 -- non-blank character other than a left parenthesis or quote. Has no
323 -- effect if manual quote mode is turned on.
325 procedure Set_Msg_Char (C : Character);
326 -- Add a single character to the current message. This routine does not
327 -- check for special insertion characters (they are just treated as text
328 -- characters if they occur).
330 procedure Set_Msg_Insertion_Column;
331 -- Handle column number insertion (@ insertion character)
333 procedure Set_Msg_Insertion_Name;
334 -- Handle name insertion (% insertion character)
336 procedure Set_Msg_Insertion_Line_Number (Loc, Flag : Source_Ptr);
337 -- Handle line number insertion (# insertion character). Loc is the
338 -- location to be referenced, and Flag is the location at which the
339 -- flag is posted (used to determine whether to add "in file xxx")
341 procedure Set_Msg_Insertion_Node;
342 -- Handle node (name from node) insertion (& insertion character)
344 procedure Set_Msg_Insertion_Reserved_Name;
345 -- Handle insertion of reserved word name (* insertion character).
347 procedure Set_Msg_Insertion_Reserved_Word
348 (Text : String;
349 J : in out Integer);
350 -- Handle reserved word insertion (upper case letters). The Text argument
351 -- is the current error message input text, and J is an index which on
352 -- entry points to the first character of the reserved word, and on exit
353 -- points past the last character of the reserved word.
355 procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr);
356 -- Handle type reference (right brace insertion character). Flag is the
357 -- location of the flag, which is provided for the internal call to
358 -- Set_Msg_Insertion_Line_Number,
360 procedure Set_Msg_Insertion_Uint;
361 -- Handle Uint insertion (^ insertion character)
363 procedure Set_Msg_Insertion_Unit_Name;
364 -- Handle unit name insertion ($ insertion character)
366 procedure Set_Msg_Insertion_File_Name;
367 -- Handle file name insertion (left brace insertion character)
369 procedure Set_Msg_Int (Line : Int);
370 -- Set the decimal representation of the argument in the error message
371 -- buffer with no leading zeroes output.
373 procedure Set_Msg_Name_Buffer;
374 -- Output name from Name_Buffer, with surrounding quotes unless manual
375 -- quotation mode is in effect.
377 procedure Set_Msg_Node (Node : Node_Id);
378 -- Add the sequence of characters for the name associated with the
379 -- given node to the current message.
381 procedure Set_Msg_Quote;
382 -- Set quote if in normal quote mode, nothing if in manual quote mode
384 procedure Set_Msg_Str (Text : String);
385 -- Add a sequence of characters to the current message. This routine does
386 -- not check for special insertion characters (they are just treated as
387 -- text characters if they occur).
389 procedure Set_Msg_Text (Text : String; Flag : Source_Ptr);
390 -- Add a sequence of characters to the current message. The characters may
391 -- be one of the special insertion characters (see documentation in spec).
392 -- Flag is the location at which the error is to be posted, which is used
393 -- to determine whether or not the # insertion needs a file name. The
394 -- variables Msg_Buffer, Msglen, Is_Warning_Msg, and Is_Unconditional_Msg
395 -- are set on return.
397 procedure Set_Posted (N : Node_Id);
398 -- Sets the Error_Posted flag on the given node, and all its parents
399 -- that are subexpressions and then on the parent non-subexpression
400 -- construct that contains the original expression (this reduces the
401 -- number of cascaded messages)
403 procedure Set_Qualification (N : Nat; E : Entity_Id);
404 -- Outputs up to N levels of qualification for the given entity. For
405 -- example, the entity A.B.C.D will output B.C. if N = 2.
407 function Special_Msg_Delete
408 (Msg : String;
409 N : Node_Or_Entity_Id;
410 E : Node_Or_Entity_Id)
411 return Boolean;
412 -- This function is called from Error_Msg_NEL, passing the message Msg,
413 -- node N on which the error is to be posted, and the entity or node E
414 -- to be used for an & insertion in the message if any. The job of this
415 -- procedure is to test for certain cascaded messages that we would like
416 -- to suppress. If the message is to be suppressed then we return True.
417 -- If the message should be generated (the normal case) False is returned.
419 procedure Test_Warning_Msg (Msg : String);
420 -- Sets Is_Warning_Msg true if Msg is a warning message (contains a
421 -- question mark character), and False otherwise.
423 procedure Unwind_Internal_Type (Ent : in out Entity_Id);
424 -- This procedure is given an entity id for an internal type, i.e.
425 -- a type with an internal name. It unwinds the type to try to get
426 -- to something reasonably printable, generating prefixes like
427 -- "subtype of", "access to", etc along the way in the buffer. The
428 -- value in Ent on return is the final name to be printed. Hopefully
429 -- this is not an internal name, but in some internal name cases, it
430 -- is an internal name, and has to be printed anyway (although in this
431 -- case the message has been killed if possible). The global variable
432 -- Class_Flag is set to True if the resulting entity should have
433 -- 'Class appended to its name (see Add_Class procedure), and is
434 -- otherwise unchanged.
436 function Warnings_Suppressed (Loc : Source_Ptr) return Boolean;
437 -- Determines if given location is covered by a warnings off suppression
438 -- range in the warnings table (or is suppressed by compilation option,
439 -- which generates a warning range for the whole source file).
441 ---------------
442 -- Add_Class --
443 ---------------
445 procedure Add_Class is
446 begin
447 if Class_Flag then
448 Class_Flag := False;
449 Set_Msg_Char (''');
450 Get_Name_String (Name_Class);
451 Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case);
452 Set_Msg_Name_Buffer;
453 end if;
454 end Add_Class;
456 ----------------------
457 -- Buffer_Ends_With --
458 ----------------------
460 function Buffer_Ends_With (S : String) return Boolean is
461 Len : constant Natural := S'Length;
463 begin
464 return
465 Msglen > Len
466 and then Msg_Buffer (Msglen - Len) = ' '
467 and then Msg_Buffer (Msglen - Len + 1 .. Msglen) = S;
468 end Buffer_Ends_With;
470 -------------------
471 -- Buffer_Remove --
472 -------------------
474 procedure Buffer_Remove (S : String) is
475 begin
476 if Buffer_Ends_With (S) then
477 Msglen := Msglen - S'Length;
478 end if;
479 end Buffer_Remove;
481 -----------------------
482 -- Change_Error_Text --
483 -----------------------
485 procedure Change_Error_Text (Error_Id : Error_Msg_Id; New_Msg : String) is
486 Save_Next : Error_Msg_Id;
487 Err_Id : Error_Msg_Id := Error_Id;
489 begin
490 Set_Msg_Text (New_Msg, Errors.Table (Error_Id).Sptr);
491 Errors.Table (Error_Id).Text := new String'(Msg_Buffer (1 .. Msglen));
493 -- If in immediate error message mode, output modified error message now
494 -- This is just a bit tricky, because we want to output just a single
495 -- message, and the messages we modified is already linked in. We solve
496 -- this by temporarily resetting its forward pointer to empty.
498 if Debug_Flag_OO then
499 Save_Next := Errors.Table (Error_Id).Next;
500 Errors.Table (Error_Id).Next := No_Error_Msg;
501 Write_Eol;
502 Output_Source_Line
503 (Errors.Table (Error_Id).Line, Errors.Table (Error_Id).Sfile, True);
504 Output_Error_Msgs (Err_Id);
505 Errors.Table (Error_Id).Next := Save_Next;
506 end if;
507 end Change_Error_Text;
509 -----------------------------
510 -- Check_Duplicate_Message --
511 -----------------------------
513 procedure Check_Duplicate_Message (M1, M2 : Error_Msg_Id) is
514 L1, L2 : Error_Msg_Id;
515 N1, N2 : Error_Msg_Id;
517 procedure Delete_Msg (Delete, Keep : Error_Msg_Id);
518 -- Called to delete message Delete, keeping message Keep. Marks
519 -- all messages of Delete with deleted flag set to True, and also
520 -- makes sure that for the error messages that are retained the
521 -- preferred message is the one retained (we prefer the shorter
522 -- one in the case where one has an Instance tag). Note that we
523 -- always know that Keep has at least as many continuations as
524 -- Delete (since we always delete the shorter sequence).
526 ----------------
527 -- Delete_Msg --
528 ----------------
530 procedure Delete_Msg (Delete, Keep : Error_Msg_Id) is
531 D, K : Error_Msg_Id;
533 begin
534 D := Delete;
535 K := Keep;
537 loop
538 Errors.Table (D).Deleted := True;
540 -- Adjust error message count
542 if Errors.Table (D).Warn then
543 Warnings_Detected := Warnings_Detected - 1;
544 else
545 Total_Errors_Detected := Total_Errors_Detected - 1;
547 if Errors.Table (D).Serious then
548 Serious_Errors_Detected := Serious_Errors_Detected - 1;
549 end if;
550 end if;
552 -- Substitute shorter of the two error messages
554 if Errors.Table (K).Text'Length > Errors.Table (D).Text'Length then
555 Errors.Table (K).Text := Errors.Table (D).Text;
556 end if;
558 D := Errors.Table (D).Next;
559 K := Errors.Table (K).Next;
561 if D = No_Error_Msg or else not Errors.Table (D).Msg_Cont then
562 return;
563 end if;
564 end loop;
565 end Delete_Msg;
567 -- Start of processing for Check_Duplicate_Message
569 begin
570 -- Both messages must be non-continuation messages and not deleted
572 if Errors.Table (M1).Msg_Cont
573 or else Errors.Table (M2).Msg_Cont
574 or else Errors.Table (M1).Deleted
575 or else Errors.Table (M2).Deleted
576 then
577 return;
578 end if;
580 -- Definitely not equal if message text does not match
582 if not Same_Error (M1, M2) then
583 return;
584 end if;
586 -- Same text. See if all continuations are also identical
588 L1 := M1;
589 L2 := M2;
591 loop
592 N1 := Errors.Table (L1).Next;
593 N2 := Errors.Table (L2).Next;
595 -- If M1 continuations have run out, we delete M1, either the
596 -- messages have the same number of continuations, or M2 has
597 -- more and we prefer the one with more anyway.
599 if N1 = No_Error_Msg or else not Errors.Table (N1).Msg_Cont then
600 Delete_Msg (M1, M2);
601 return;
603 -- If M2 continuatins have run out, we delete M2
605 elsif N2 = No_Error_Msg or else not Errors.Table (N2).Msg_Cont then
606 Delete_Msg (M2, M1);
607 return;
609 -- Otherwise see if continuations are the same, if not, keep both
610 -- sequences, a curious case, but better to keep everything!
612 elsif not Same_Error (N1, N2) then
613 return;
615 -- If continuations are the same, continue scan
617 else
618 L1 := N1;
619 L2 := N2;
620 end if;
621 end loop;
622 end Check_Duplicate_Message;
624 ------------------------
625 -- Compilation_Errors --
626 ------------------------
628 function Compilation_Errors return Boolean is
629 begin
630 return Total_Errors_Detected /= 0
631 or else (Warnings_Detected /= 0
632 and then Warning_Mode = Treat_As_Error);
633 end Compilation_Errors;
635 ------------------
636 -- Debug_Output --
637 ------------------
639 procedure Debug_Output (N : Node_Id) is
640 begin
641 if Debug_Flag_1 then
642 Write_Str ("*** following error message posted on node id = #");
643 Write_Int (Int (N));
644 Write_Str (" ***");
645 Write_Eol;
646 end if;
647 end Debug_Output;
649 ----------
650 -- dmsg --
651 ----------
653 procedure dmsg (Id : Error_Msg_Id) is
654 E : Error_Msg_Object renames Errors.Table (Id);
656 begin
657 w ("Dumping error message, Id = ", Int (Id));
658 w (" Text = ", E.Text.all);
659 w (" Next = ", Int (E.Next));
660 w (" Sfile = ", Int (E.Sfile));
662 Write_Str
663 (" Sptr = ");
664 Write_Location (E.Sptr);
665 Write_Eol;
667 Write_Str
668 (" Fptr = ");
669 Write_Location (E.Fptr);
670 Write_Eol;
672 w (" Line = ", Int (E.Line));
673 w (" Col = ", Int (E.Col));
674 w (" Warn = ", E.Warn);
675 w (" Serious = ", E.Serious);
676 w (" Uncond = ", E.Uncond);
677 w (" Msg_Cont = ", E.Msg_Cont);
678 w (" Deleted = ", E.Deleted);
680 Write_Eol;
681 end dmsg;
683 ---------------
684 -- Error_Msg --
685 ---------------
687 -- Error_Msg posts a flag at the given location, except that if the
688 -- Flag_Location points within a generic template and corresponds
689 -- to an instantiation of this generic template, then the actual
690 -- message will be posted on the generic instantiation, along with
691 -- additional messages referencing the generic declaration.
693 procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is
694 Sindex : Source_File_Index;
695 -- Source index for flag location
697 Orig_Loc : Source_Ptr;
698 -- Original location of Flag_Location (i.e. location in original
699 -- template in instantiation case, otherwise unchanged).
701 begin
702 -- If we already have messages, and we are trying to place a message
703 -- at No_Location or in package Standard, then just ignore the attempt
704 -- since we assume that what is happening is some cascaded junk. Note
705 -- that this is safe in the sense that proceeding will surely bomb.
707 if Flag_Location < First_Source_Ptr
708 and then Total_Errors_Detected > 0
709 then
710 return;
711 end if;
713 Sindex := Get_Source_File_Index (Flag_Location);
714 Test_Warning_Msg (Msg);
716 -- It is a fatal error to issue an error message when scanning from
717 -- the internal source buffer (see Sinput for further documentation)
719 pragma Assert (Source /= Internal_Source_Ptr);
721 -- Ignore warning message that is suppressed
723 Orig_Loc := Original_Location (Flag_Location);
725 if Is_Warning_Msg and then Warnings_Suppressed (Orig_Loc) then
726 return;
727 end if;
729 -- The idea at this stage is that we have two kinds of messages.
731 -- First, we have those that are to be placed as requested at
732 -- Flag_Location. This includes messages that have nothing to
733 -- do with generics, and also messages placed on generic templates
734 -- that reflect an error in the template itself. For such messages
735 -- we simply call Error_Msg_Internal to place the message in the
736 -- requested location.
738 if Instantiation (Sindex) = No_Location then
739 Error_Msg_Internal (Msg, Flag_Location, False);
740 return;
741 end if;
743 -- If we are trying to flag an error in an instantiation, we may have
744 -- a generic contract violation. What we generate in this case is:
746 -- instantiation error at ...
747 -- original error message
749 -- or
751 -- warning: in instantiation at
752 -- warning: original warning message
754 -- All these messages are posted at the location of the top level
755 -- instantiation. If there are nested instantiations, then the
756 -- instantiation error message can be repeated, pointing to each
757 -- of the relevant instantiations.
759 -- However, before we do this, we need to worry about the case where
760 -- indeed we are in an instantiation, but the message is a warning
761 -- message. In this case, it almost certainly a warning for the
762 -- template itself and so it is posted on the template. At least
763 -- this is the default mode, it can be cancelled (resulting the
764 -- warning being placed on the instance as in the error case) by
765 -- setting the global Warn_On_Instance True.
767 if (not Warn_On_Instance) and then Is_Warning_Msg then
768 Error_Msg_Internal (Msg, Flag_Location, False);
769 return;
770 end if;
772 -- Second, we need to worry about the case where there was a real error
773 -- in the template, and we are getting a repeat of this error in the
774 -- instantiation. We don't want to complain about the instantiation
775 -- in this case, since we have already flagged the template.
777 -- To deal with this case, just see if we have posted a message at
778 -- the template location already. If so, assume that the current
779 -- message is redundant. There could be cases in which this is not
780 -- a correct assumption, but it is not terrible to lose a message
781 -- about an incorrect instantiation given that we have already
782 -- flagged a message on the template.
784 for Err in Errors.First .. Errors.Last loop
785 if Errors.Table (Err).Sptr = Orig_Loc then
787 -- If the current message is a real error, as opposed to a
788 -- warning, then we don't want to let a warning on the
789 -- template inhibit a real error on the instantiation.
791 if Is_Warning_Msg
792 or else not Errors.Table (Err).Warn
793 then
794 return;
795 end if;
796 end if;
797 end loop;
799 -- OK, this is the case where we have an instantiation error, and
800 -- we need to generate the error on the instantiation, rather than
801 -- on the template. First, see if we have posted this exact error
802 -- before, and if so suppress it. It is not so easy to use the main
803 -- list of errors for this, since they have already been split up
804 -- according to the processing below. Consequently we use an auxiliary
805 -- data structure that just records these types of messages (it will
806 -- never have very many entries).
808 declare
809 Actual_Error_Loc : Source_Ptr;
810 -- Location of outer level instantiation in instantiation case, or
811 -- just a copy of Flag_Location in the normal case. This is the
812 -- location where all error messages will actually be posted.
814 Save_Error_Msg_Sloc : constant Source_Ptr := Error_Msg_Sloc;
815 -- Save possible location set for caller's message. We need to
816 -- use Error_Msg_Sloc for the location of the instantiation error
817 -- but we have to preserve a possible original value.
819 X : Source_File_Index;
821 Msg_Cont_Status : Boolean;
822 -- Used to label continuation lines in instantiation case with
823 -- proper Msg_Cont status.
825 begin
826 -- Loop to find highest level instantiation, where all error
827 -- messages will be placed.
829 X := Sindex;
830 loop
831 Actual_Error_Loc := Instantiation (X);
832 X := Get_Source_File_Index (Actual_Error_Loc);
833 exit when Instantiation (X) = No_Location;
834 end loop;
836 -- Since we are generating the messages at the instantiation
837 -- point in any case, we do not want the references to the
838 -- bad lines in the instance to be annotated with the location
839 -- of the instantiation.
841 Suppress_Instance_Location := True;
842 Msg_Cont_Status := False;
844 -- Loop to generate instantiation messages
846 Error_Msg_Sloc := Flag_Location;
847 X := Get_Source_File_Index (Flag_Location);
849 while Instantiation (X) /= No_Location loop
851 -- Suppress instantiation message on continuation lines
853 if Msg (1) /= '\' then
854 if Is_Warning_Msg then
855 Error_Msg_Internal
856 ("?in instantiation #",
857 Actual_Error_Loc, Msg_Cont_Status);
859 else
860 Error_Msg_Internal
861 ("instantiation error #",
862 Actual_Error_Loc, Msg_Cont_Status);
863 end if;
864 end if;
866 Error_Msg_Sloc := Instantiation (X);
867 X := Get_Source_File_Index (Error_Msg_Sloc);
868 Msg_Cont_Status := True;
869 end loop;
871 Suppress_Instance_Location := False;
872 Error_Msg_Sloc := Save_Error_Msg_Sloc;
874 -- Here we output the original message on the outer instantiation
876 Error_Msg_Internal (Msg, Actual_Error_Loc, Msg_Cont_Status);
877 end;
878 end Error_Msg;
880 ------------------
881 -- Error_Msg_AP --
882 ------------------
884 procedure Error_Msg_AP (Msg : String) is
885 S1 : Source_Ptr;
886 C : Character;
888 begin
889 -- If we had saved the Scan_Ptr value after scanning the previous
890 -- token, then we would have exactly the right place for putting
891 -- the flag immediately at hand. However, that would add at least
892 -- two instructions to a Scan call *just* to service the possibility
893 -- of an Error_Msg_AP call. So instead we reconstruct that value.
895 -- We have two possibilities, start with Prev_Token_Ptr and skip over
896 -- the current token, which is made harder by the possibility that this
897 -- token may be in error, or start with Token_Ptr and work backwards.
898 -- We used to take the second approach, but it's hard because of
899 -- comments, and harder still because things that look like comments
900 -- can appear inside strings. So now we take the first approach.
902 -- Note: in the case where there is no previous token, Prev_Token_Ptr
903 -- is set to Source_First, which is a reasonable position for the
904 -- error flag in this situation.
906 S1 := Prev_Token_Ptr;
907 C := Source (S1);
909 -- If the previous token is a string literal, we need a special approach
910 -- since there may be white space inside the literal and we don't want
911 -- to stop on that white space.
913 if Prev_Token = Tok_String_Literal then
914 loop
915 S1 := S1 + 1;
917 if Source (S1) = C then
918 S1 := S1 + 1;
919 exit when Source (S1) /= C;
920 elsif Source (S1) in Line_Terminator then
921 exit;
922 end if;
923 end loop;
925 -- Character literal also needs special handling
927 elsif Prev_Token = Tok_Char_Literal then
928 S1 := S1 + 3;
930 -- Otherwise we search forward for the end of the current token, marked
931 -- by a line terminator, white space, a comment symbol or if we bump
932 -- into the following token (i.e. the current token)
934 else
935 while Source (S1) not in Line_Terminator
936 and then Source (S1) /= ' '
937 and then Source (S1) /= ASCII.HT
938 and then (Source (S1) /= '-' or else Source (S1 + 1) /= '-')
939 and then S1 /= Token_Ptr
940 loop
941 S1 := S1 + 1;
942 end loop;
943 end if;
945 -- S1 is now set to the location for the flag
947 Error_Msg (Msg, S1);
949 end Error_Msg_AP;
951 ------------------
952 -- Error_Msg_BC --
953 ------------------
955 procedure Error_Msg_BC (Msg : String) is
956 begin
957 -- If we are at end of file, post the flag after the previous token
959 if Token = Tok_EOF then
960 Error_Msg_AP (Msg);
962 -- If we are at start of file, post the flag at the current token
964 elsif Token_Ptr = Source_First (Current_Source_File) then
965 Error_Msg_SC (Msg);
967 -- If the character before the current token is a space or a horizontal
968 -- tab, then we place the flag on this character (in the case of a tab
969 -- we would really like to place it in the "last" character of the tab
970 -- space, but that it too much trouble to worry about).
972 elsif Source (Token_Ptr - 1) = ' '
973 or else Source (Token_Ptr - 1) = ASCII.HT
974 then
975 Error_Msg (Msg, Token_Ptr - 1);
977 -- If there is no space or tab before the current token, then there is
978 -- no room to place the flag before the token, so we place it on the
979 -- token instead (this happens for example at the start of a line).
981 else
982 Error_Msg (Msg, Token_Ptr);
983 end if;
984 end Error_Msg_BC;
986 ------------------------
987 -- Error_Msg_Internal --
988 ------------------------
990 procedure Error_Msg_Internal
991 (Msg : String;
992 Flag_Location : Source_Ptr;
993 Msg_Cont : Boolean)
995 Next_Msg : Error_Msg_Id;
996 -- Pointer to next message at insertion point
998 Prev_Msg : Error_Msg_Id;
999 -- Pointer to previous message at insertion point
1001 Temp_Msg : Error_Msg_Id;
1003 Orig_Loc : constant Source_Ptr := Original_Location (Flag_Location);
1005 procedure Handle_Serious_Error;
1006 -- Internal procedure to do all error message handling for a serious
1007 -- error message, other than bumping the error counts and arranging
1008 -- for the message to be output.
1010 --------------------------
1011 -- Handle_Serious_Error --
1012 --------------------------
1014 procedure Handle_Serious_Error is
1015 begin
1016 -- Turn off code generation if not done already
1018 if Operating_Mode = Generate_Code then
1019 Operating_Mode := Check_Semantics;
1020 Expander_Active := False;
1021 end if;
1023 -- Set the fatal error flag in the unit table unless we are
1024 -- in Try_Semantics mode. This stops the semantics from being
1025 -- performed if we find a serious error. This is skipped if we
1026 -- are currently dealing with the configuration pragma file.
1028 if not Try_Semantics
1029 and then Current_Source_Unit /= No_Unit
1030 then
1031 Set_Fatal_Error (Get_Source_Unit (Orig_Loc));
1032 end if;
1033 end Handle_Serious_Error;
1035 -- Start of processing for Error_Msg_Internal
1037 begin
1038 if Raise_Exception_On_Error /= 0 then
1039 raise Error_Msg_Exception;
1040 end if;
1042 Continuation := Msg_Cont;
1043 Suppress_Message := False;
1044 Kill_Message := False;
1045 Set_Msg_Text (Msg, Orig_Loc);
1047 -- Kill continuation if parent message killed
1049 if Continuation and Last_Killed then
1050 return;
1051 end if;
1053 -- Return without doing anything if message is suppressed
1055 if Suppress_Message
1056 and not All_Errors_Mode
1057 and not (Msg (Msg'Last) = '!')
1058 then
1059 if not Continuation then
1060 Last_Killed := True;
1061 end if;
1063 return;
1064 end if;
1066 -- Return without doing anything if message is killed and this
1067 -- is not the first error message. The philosophy is that if we
1068 -- get a weird error message and we already have had a message,
1069 -- then we hope the weird message is a junk cascaded message
1071 if Kill_Message
1072 and then not All_Errors_Mode
1073 and then Total_Errors_Detected /= 0
1074 then
1075 if not Continuation then
1076 Last_Killed := True;
1077 end if;
1079 return;
1080 end if;
1082 -- Immediate return if warning message and warnings are suppressed
1084 if Is_Warning_Msg and then Warnings_Suppressed (Orig_Loc) then
1085 Cur_Msg := No_Error_Msg;
1086 return;
1087 end if;
1089 -- If message is to be ignored in special ignore message mode, this is
1090 -- where we do this special processing, bypassing message output.
1092 if Ignore_Errors_Enable > 0 then
1093 if Is_Serious_Error then
1094 Handle_Serious_Error;
1095 end if;
1097 return;
1098 end if;
1100 -- Otherwise build error message object for new message
1102 Errors.Increment_Last;
1103 Cur_Msg := Errors.Last;
1104 Errors.Table (Cur_Msg).Text := new String'(Msg_Buffer (1 .. Msglen));
1105 Errors.Table (Cur_Msg).Next := No_Error_Msg;
1106 Errors.Table (Cur_Msg).Sptr := Orig_Loc;
1107 Errors.Table (Cur_Msg).Fptr := Flag_Location;
1108 Errors.Table (Cur_Msg).Sfile := Get_Source_File_Index (Orig_Loc);
1109 Errors.Table (Cur_Msg).Line := Get_Physical_Line_Number (Orig_Loc);
1110 Errors.Table (Cur_Msg).Col := Get_Column_Number (Orig_Loc);
1111 Errors.Table (Cur_Msg).Warn := Is_Warning_Msg;
1112 Errors.Table (Cur_Msg).Serious := Is_Serious_Error;
1113 Errors.Table (Cur_Msg).Uncond := Is_Unconditional_Msg;
1114 Errors.Table (Cur_Msg).Msg_Cont := Continuation;
1115 Errors.Table (Cur_Msg).Deleted := False;
1117 -- If immediate errors mode set, output error message now. Also output
1118 -- now if the -d1 debug flag is set (so node number message comes out
1119 -- just before actual error message)
1121 if Debug_Flag_OO or else Debug_Flag_1 then
1122 Write_Eol;
1123 Output_Source_Line (Errors.Table (Cur_Msg).Line,
1124 Errors.Table (Cur_Msg).Sfile, True);
1125 Temp_Msg := Cur_Msg;
1126 Output_Error_Msgs (Temp_Msg);
1128 -- If not in immediate errors mode, then we insert the message in the
1129 -- error chain for later output by Finalize. The messages are sorted
1130 -- first by unit (main unit comes first), and within a unit by source
1131 -- location (earlier flag location first in the chain).
1133 else
1134 Prev_Msg := No_Error_Msg;
1135 Next_Msg := Error_Msgs;
1137 while Next_Msg /= No_Error_Msg loop
1138 exit when
1139 Errors.Table (Cur_Msg).Sfile < Errors.Table (Next_Msg).Sfile;
1141 if Errors.Table (Cur_Msg).Sfile =
1142 Errors.Table (Next_Msg).Sfile
1143 then
1144 exit when Orig_Loc < Errors.Table (Next_Msg).Sptr;
1145 end if;
1147 Prev_Msg := Next_Msg;
1148 Next_Msg := Errors.Table (Next_Msg).Next;
1149 end loop;
1151 -- Now we insert the new message in the error chain. The insertion
1152 -- point for the message is after Prev_Msg and before Next_Msg.
1154 -- The possible insertion point for the new message is after Prev_Msg
1155 -- and before Next_Msg. However, this is where we do a special check
1156 -- for redundant parsing messages, defined as messages posted on the
1157 -- same line. The idea here is that probably such messages are junk
1158 -- from the parser recovering. In full errors mode, we don't do this
1159 -- deletion, but otherwise such messages are discarded at this stage.
1161 if Prev_Msg /= No_Error_Msg
1162 and then Errors.Table (Prev_Msg).Line =
1163 Errors.Table (Cur_Msg).Line
1164 and then Errors.Table (Prev_Msg).Sfile =
1165 Errors.Table (Cur_Msg).Sfile
1166 and then Compiler_State = Parsing
1167 and then not All_Errors_Mode
1168 then
1169 -- Don't delete unconditional messages and at this stage,
1170 -- don't delete continuation lines (we attempted to delete
1171 -- those earlier if the parent message was deleted.
1173 if not Errors.Table (Cur_Msg).Uncond
1174 and then not Continuation
1175 then
1177 -- Don't delete if prev msg is warning and new msg is
1178 -- an error. This is because we don't want a real error
1179 -- masked by a warning. In all other cases (that is parse
1180 -- errors for the same line that are not unconditional)
1181 -- we do delete the message. This helps to avoid
1182 -- junk extra messages from cascaded parsing errors
1184 if not Errors.Table (Prev_Msg).Warn
1185 or else Errors.Table (Cur_Msg).Warn
1186 then
1187 -- All tests passed, delete the message by simply
1188 -- returning without any further processing.
1190 if not Continuation then
1191 Last_Killed := True;
1192 end if;
1194 return;
1195 end if;
1196 end if;
1197 end if;
1199 -- Come here if message is to be inserted in the error chain
1201 if not Continuation then
1202 Last_Killed := False;
1203 end if;
1205 if Prev_Msg = No_Error_Msg then
1206 Error_Msgs := Cur_Msg;
1207 else
1208 Errors.Table (Prev_Msg).Next := Cur_Msg;
1209 end if;
1211 Errors.Table (Cur_Msg).Next := Next_Msg;
1212 end if;
1214 -- Bump appropriate statistics count
1216 if Errors.Table (Cur_Msg).Warn then
1217 Warnings_Detected := Warnings_Detected + 1;
1218 else
1219 Total_Errors_Detected := Total_Errors_Detected + 1;
1221 if Errors.Table (Cur_Msg).Serious then
1222 Serious_Errors_Detected := Serious_Errors_Detected + 1;
1223 Handle_Serious_Error;
1224 end if;
1225 end if;
1227 -- Terminate if max errors reached
1229 if Total_Errors_Detected + Warnings_Detected = Maximum_Errors then
1230 raise Unrecoverable_Error;
1231 end if;
1233 end Error_Msg_Internal;
1235 -----------------
1236 -- Error_Msg_N --
1237 -----------------
1239 procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id) is
1240 begin
1241 Error_Msg_NEL (Msg, N, N, Sloc (N));
1242 end Error_Msg_N;
1244 ------------------
1245 -- Error_Msg_NE --
1246 ------------------
1248 procedure Error_Msg_NE
1249 (Msg : String;
1250 N : Node_Or_Entity_Id;
1251 E : Node_Or_Entity_Id)
1253 begin
1254 Error_Msg_NEL (Msg, N, E, Sloc (N));
1255 end Error_Msg_NE;
1257 -------------------
1258 -- Error_Msg_NEL --
1259 -------------------
1261 procedure Error_Msg_NEL
1262 (Msg : String;
1263 N : Node_Or_Entity_Id;
1264 E : Node_Or_Entity_Id;
1265 Flag_Location : Source_Ptr)
1267 begin
1268 if Special_Msg_Delete (Msg, N, E) then
1269 return;
1270 end if;
1272 if No_Warnings (N) or else No_Warnings (E) then
1273 Test_Warning_Msg (Msg);
1275 if Is_Warning_Msg then
1276 return;
1277 end if;
1278 end if;
1280 if All_Errors_Mode
1281 or else Msg (Msg'Last) = '!'
1282 or else OK_Node (N)
1283 or else (Msg (1) = '\' and not Last_Killed)
1284 then
1285 Debug_Output (N);
1286 Error_Msg_Node_1 := E;
1287 Error_Msg (Msg, Flag_Location);
1289 else
1290 Last_Killed := True;
1291 end if;
1293 if not Is_Warning_Msg then
1294 Set_Posted (N);
1295 end if;
1296 end Error_Msg_NEL;
1298 -----------------
1299 -- Error_Msg_S --
1300 -----------------
1302 procedure Error_Msg_S (Msg : String) is
1303 begin
1304 Error_Msg (Msg, Scan_Ptr);
1305 end Error_Msg_S;
1307 ------------------
1308 -- Error_Msg_SC --
1309 ------------------
1311 procedure Error_Msg_SC (Msg : String) is
1312 begin
1313 -- If we are at end of file, post the flag after the previous token
1315 if Token = Tok_EOF then
1316 Error_Msg_AP (Msg);
1318 -- For all other cases the message is posted at the current token
1319 -- pointer position
1321 else
1322 Error_Msg (Msg, Token_Ptr);
1323 end if;
1324 end Error_Msg_SC;
1326 ------------------
1327 -- Error_Msg_SP --
1328 ------------------
1330 procedure Error_Msg_SP (Msg : String) is
1331 begin
1332 -- Note: in the case where there is no previous token, Prev_Token_Ptr
1333 -- is set to Source_First, which is a reasonable position for the
1334 -- error flag in this situation
1336 Error_Msg (Msg, Prev_Token_Ptr);
1337 end Error_Msg_SP;
1339 --------------
1340 -- Finalize --
1341 --------------
1343 procedure Finalize is
1344 Cur : Error_Msg_Id;
1345 Nxt : Error_Msg_Id;
1346 E, F : Error_Msg_Id;
1347 Err_Flag : Boolean;
1349 begin
1350 -- Reset current error source file if the main unit has a pragma
1351 -- Source_Reference. This ensures outputting the proper name of
1352 -- the source file in this situation.
1354 if Num_SRef_Pragmas (Main_Source_File) /= 0 then
1355 Current_Error_Source_File := No_Source_File;
1356 end if;
1358 -- Eliminate any duplicated error messages from the list. This is
1359 -- done after the fact to avoid problems with Change_Error_Text.
1361 Cur := Error_Msgs;
1362 while Cur /= No_Error_Msg loop
1363 Nxt := Errors.Table (Cur).Next;
1365 F := Nxt;
1366 while F /= No_Error_Msg
1367 and then Errors.Table (F).Sptr = Errors.Table (Cur).Sptr
1368 loop
1369 Check_Duplicate_Message (Cur, F);
1370 F := Errors.Table (F).Next;
1371 end loop;
1373 Cur := Nxt;
1374 end loop;
1376 -- Brief Error mode
1378 if Brief_Output or (not Full_List and not Verbose_Mode) then
1379 E := Error_Msgs;
1380 Set_Standard_Error;
1382 while E /= No_Error_Msg loop
1383 if not Errors.Table (E).Deleted and then not Debug_Flag_KK then
1384 Write_Name (Reference_Name (Errors.Table (E).Sfile));
1385 Write_Char (':');
1386 Write_Int (Int (Physical_To_Logical
1387 (Errors.Table (E).Line,
1388 Errors.Table (E).Sfile)));
1389 Write_Char (':');
1391 if Errors.Table (E).Col < 10 then
1392 Write_Char ('0');
1393 end if;
1395 Write_Int (Int (Errors.Table (E).Col));
1396 Write_Str (": ");
1397 Output_Msg_Text (E);
1398 Write_Eol;
1399 end if;
1401 E := Errors.Table (E).Next;
1402 end loop;
1404 Set_Standard_Output;
1405 end if;
1407 -- Full source listing case
1409 if Full_List then
1410 List_Pragmas_Index := 1;
1411 List_Pragmas_Mode := True;
1412 E := Error_Msgs;
1413 Write_Eol;
1415 -- First list initial main source file with its error messages
1417 for N in 1 .. Last_Source_Line (Main_Source_File) loop
1418 Err_Flag :=
1419 E /= No_Error_Msg
1420 and then Errors.Table (E).Line = N
1421 and then Errors.Table (E).Sfile = Main_Source_File;
1423 Output_Source_Line (N, Main_Source_File, Err_Flag);
1425 if Err_Flag then
1426 Output_Error_Msgs (E);
1428 if not Debug_Flag_2 then
1429 Write_Eol;
1430 end if;
1431 end if;
1433 end loop;
1435 -- Then output errors, if any, for subsidiary units
1437 while E /= No_Error_Msg
1438 and then Errors.Table (E).Sfile /= Main_Source_File
1439 loop
1440 Write_Eol;
1441 Output_Source_Line
1442 (Errors.Table (E).Line, Errors.Table (E).Sfile, True);
1443 Output_Error_Msgs (E);
1444 end loop;
1445 end if;
1447 -- Verbose mode (error lines only with error flags)
1449 if Verbose_Mode and not Full_List then
1450 E := Error_Msgs;
1452 -- Loop through error lines
1454 while E /= No_Error_Msg loop
1455 Write_Eol;
1456 Output_Source_Line
1457 (Errors.Table (E).Line, Errors.Table (E).Sfile, True);
1458 Output_Error_Msgs (E);
1459 end loop;
1460 end if;
1462 -- Output error summary if verbose or full list mode
1464 if Verbose_Mode or else Full_List then
1466 -- Extra blank line if error messages or source listing were output
1468 if Total_Errors_Detected + Warnings_Detected > 0
1469 or else Full_List
1470 then
1471 Write_Eol;
1472 end if;
1474 -- Message giving number of lines read and number of errors detected.
1475 -- This normally goes to Standard_Output. The exception is when brief
1476 -- mode is not set, verbose mode (or full list mode) is set, and
1477 -- there are errors. In this case we send the message to standard
1478 -- error to make sure that *something* appears on standard error in
1479 -- an error situation.
1481 -- Formerly, only the "# errors" suffix was sent to stderr, whereas
1482 -- "# lines:" appeared on stdout. This caused problems on VMS when
1483 -- the stdout buffer was flushed, giving an extra line feed after
1484 -- the prefix.
1486 if Total_Errors_Detected + Warnings_Detected /= 0
1487 and then not Brief_Output
1488 and then (Verbose_Mode or Full_List)
1489 then
1490 Set_Standard_Error;
1491 end if;
1493 -- Message giving total number of lines
1495 Write_Str (" ");
1496 Write_Int (Num_Source_Lines (Main_Source_File));
1498 if Num_Source_Lines (Main_Source_File) = 1 then
1499 Write_Str (" line: ");
1500 else
1501 Write_Str (" lines: ");
1502 end if;
1504 if Total_Errors_Detected = 0 then
1505 Write_Str ("No errors");
1507 elsif Total_Errors_Detected = 1 then
1508 Write_Str ("1 error");
1510 else
1511 Write_Int (Total_Errors_Detected);
1512 Write_Str (" errors");
1513 end if;
1515 if Warnings_Detected /= 0 then
1516 Write_Str (", ");
1517 Write_Int (Warnings_Detected);
1518 Write_Str (" warning");
1520 if Warnings_Detected /= 1 then
1521 Write_Char ('s');
1522 end if;
1524 if Warning_Mode = Treat_As_Error then
1525 Write_Str (" (treated as error");
1527 if Warnings_Detected /= 1 then
1528 Write_Char ('s');
1529 end if;
1531 Write_Char (')');
1532 end if;
1533 end if;
1535 Write_Eol;
1536 Set_Standard_Output;
1537 end if;
1539 if Maximum_Errors /= 0
1540 and then Total_Errors_Detected + Warnings_Detected = Maximum_Errors
1541 then
1542 Set_Standard_Error;
1543 Write_Str ("fatal error: maximum errors reached");
1544 Write_Eol;
1545 Set_Standard_Output;
1546 end if;
1548 if Warning_Mode = Treat_As_Error then
1549 Total_Errors_Detected := Total_Errors_Detected + Warnings_Detected;
1550 Warnings_Detected := 0;
1551 end if;
1553 end Finalize;
1555 ------------------
1556 -- Get_Location --
1557 ------------------
1559 function Get_Location (E : Error_Msg_Id) return Source_Ptr is
1560 begin
1561 return Errors.Table (E).Sptr;
1562 end Get_Location;
1564 ----------------
1565 -- Get_Msg_Id --
1566 ----------------
1568 function Get_Msg_Id return Error_Msg_Id is
1569 begin
1570 return Cur_Msg;
1571 end Get_Msg_Id;
1573 ----------------
1574 -- Initialize --
1575 ----------------
1577 procedure Initialize is
1578 begin
1579 Errors.Init;
1580 Error_Msgs := No_Error_Msg;
1581 Serious_Errors_Detected := 0;
1582 Total_Errors_Detected := 0;
1583 Warnings_Detected := 0;
1584 Cur_Msg := No_Error_Msg;
1585 List_Pragmas.Init;
1587 -- Initialize warnings table, if all warnings are suppressed, supply
1588 -- an initial dummy entry covering all possible source locations.
1590 Warnings.Init;
1592 if Warning_Mode = Suppress then
1593 Warnings.Increment_Last;
1594 Warnings.Table (Warnings.Last).Start := Source_Ptr'First;
1595 Warnings.Table (Warnings.Last).Stop := Source_Ptr'Last;
1596 end if;
1598 end Initialize;
1600 -----------------
1601 -- No_Warnings --
1602 -----------------
1604 function No_Warnings (N : Node_Or_Entity_Id) return Boolean is
1605 begin
1606 if Error_Posted (N) then
1607 return True;
1609 elsif Nkind (N) in N_Entity and then Warnings_Off (N) then
1610 return True;
1612 elsif Is_Entity_Name (N)
1613 and then Present (Entity (N))
1614 and then Warnings_Off (Entity (N))
1615 then
1616 return True;
1618 else
1619 return False;
1620 end if;
1621 end No_Warnings;
1623 -------------
1624 -- OK_Node --
1625 -------------
1627 function OK_Node (N : Node_Id) return Boolean is
1628 K : constant Node_Kind := Nkind (N);
1630 begin
1631 if Error_Posted (N) then
1632 return False;
1634 elsif K in N_Has_Etype
1635 and then Present (Etype (N))
1636 and then Error_Posted (Etype (N))
1637 then
1638 return False;
1640 elsif (K in N_Op
1641 or else K = N_Attribute_Reference
1642 or else K = N_Character_Literal
1643 or else K = N_Expanded_Name
1644 or else K = N_Identifier
1645 or else K = N_Operator_Symbol)
1646 and then Present (Entity (N))
1647 and then Error_Posted (Entity (N))
1648 then
1649 return False;
1650 else
1651 return True;
1652 end if;
1653 end OK_Node;
1655 -----------------------
1656 -- Output_Error_Msgs --
1657 -----------------------
1659 procedure Output_Error_Msgs (E : in out Error_Msg_Id) is
1660 P : Source_Ptr;
1661 T : Error_Msg_Id;
1662 S : Error_Msg_Id;
1664 Flag_Num : Pos;
1665 Mult_Flags : Boolean := False;
1667 begin
1668 S := E;
1670 -- Skip deleted messages at start
1672 if Errors.Table (S).Deleted then
1673 Set_Next_Non_Deleted_Msg (S);
1674 end if;
1676 -- Figure out if we will place more than one error flag on this line
1678 T := S;
1679 while T /= No_Error_Msg
1680 and then Errors.Table (T).Line = Errors.Table (E).Line
1681 and then Errors.Table (T).Sfile = Errors.Table (E).Sfile
1682 loop
1683 if Errors.Table (T).Sptr > Errors.Table (E).Sptr then
1684 Mult_Flags := True;
1685 end if;
1687 Set_Next_Non_Deleted_Msg (T);
1688 end loop;
1690 -- Output the error flags. The circuit here makes sure that the tab
1691 -- characters in the original line are properly accounted for. The
1692 -- eight blanks at the start are to match the line number.
1694 if not Debug_Flag_2 then
1695 Write_Str (" ");
1696 P := Line_Start (Errors.Table (E).Sptr);
1697 Flag_Num := 1;
1699 -- Loop through error messages for this line to place flags
1701 T := S;
1702 while T /= No_Error_Msg
1703 and then Errors.Table (T).Line = Errors.Table (E).Line
1704 and then Errors.Table (T).Sfile = Errors.Table (E).Sfile
1705 loop
1706 -- Loop to output blanks till current flag position
1708 while P < Errors.Table (T).Sptr loop
1709 if Source_Text (Errors.Table (T).Sfile) (P) = ASCII.HT then
1710 Write_Char (ASCII.HT);
1711 else
1712 Write_Char (' ');
1713 end if;
1715 P := P + 1;
1716 end loop;
1718 -- Output flag (unless already output, this happens if more
1719 -- than one error message occurs at the same flag position).
1721 if P = Errors.Table (T).Sptr then
1722 if (Flag_Num = 1 and then not Mult_Flags)
1723 or else Flag_Num > 9
1724 then
1725 Write_Char ('|');
1726 else
1727 Write_Char (Character'Val (Character'Pos ('0') + Flag_Num));
1728 end if;
1730 P := P + 1;
1731 end if;
1733 Set_Next_Non_Deleted_Msg (T);
1734 Flag_Num := Flag_Num + 1;
1735 end loop;
1737 Write_Eol;
1738 end if;
1740 -- Now output the error messages
1742 T := S;
1743 while T /= No_Error_Msg
1744 and then Errors.Table (T).Line = Errors.Table (E).Line
1745 and then Errors.Table (T).Sfile = Errors.Table (E).Sfile
1747 loop
1748 Write_Str (" >>> ");
1749 Output_Msg_Text (T);
1751 if Debug_Flag_2 then
1752 while Column < 74 loop
1753 Write_Char (' ');
1754 end loop;
1756 Write_Str (" <<<");
1757 end if;
1759 Write_Eol;
1760 Set_Next_Non_Deleted_Msg (T);
1761 end loop;
1763 E := T;
1764 end Output_Error_Msgs;
1766 ------------------------
1767 -- Output_Line_Number --
1768 ------------------------
1770 procedure Output_Line_Number (L : Logical_Line_Number) is
1771 D : Int; -- next digit
1772 C : Character; -- next character
1773 Z : Boolean; -- flag for zero suppress
1774 N, M : Int; -- temporaries
1776 begin
1777 if L = No_Line_Number then
1778 Write_Str (" ");
1780 else
1781 Z := False;
1782 N := Int (L);
1784 M := 100_000;
1785 while M /= 0 loop
1786 D := Int (N / M);
1787 N := N rem M;
1788 M := M / 10;
1790 if D = 0 then
1791 if Z then
1792 C := '0';
1793 else
1794 C := ' ';
1795 end if;
1796 else
1797 Z := True;
1798 C := Character'Val (D + 48);
1799 end if;
1801 Write_Char (C);
1802 end loop;
1804 Write_Str (". ");
1805 end if;
1806 end Output_Line_Number;
1808 ---------------------
1809 -- Output_Msg_Text --
1810 ---------------------
1812 procedure Output_Msg_Text (E : Error_Msg_Id) is
1813 begin
1814 if Errors.Table (E).Warn then
1815 if Errors.Table (E).Text'Length > 7
1816 and then Errors.Table (E).Text (1 .. 7) /= "(style)"
1817 then
1818 Write_Str ("warning: ");
1819 end if;
1821 elsif Opt.Unique_Error_Tag then
1822 Write_Str ("error: ");
1823 end if;
1825 Write_Str (Errors.Table (E).Text.all);
1826 end Output_Msg_Text;
1828 ------------------------
1829 -- Output_Source_Line --
1830 ------------------------
1832 procedure Output_Source_Line
1833 (L : Physical_Line_Number;
1834 Sfile : Source_File_Index;
1835 Errs : Boolean)
1837 S : Source_Ptr;
1838 C : Character;
1840 Line_Number_Output : Boolean := False;
1841 -- Set True once line number is output
1843 begin
1844 if Sfile /= Current_Error_Source_File then
1845 Write_Str ("==============Error messages for source file: ");
1846 Write_Name (Full_File_Name (Sfile));
1847 Write_Eol;
1849 if Num_SRef_Pragmas (Sfile) > 0 then
1850 Write_Str ("--------------Line numbers from file: ");
1851 Write_Name (Full_Ref_Name (Sfile));
1853 -- Write starting line, except do not write it if we had more
1854 -- than one source reference pragma, since in this case there
1855 -- is no very useful number to write.
1857 Write_Str (" (starting at line ");
1858 Write_Int (Int (First_Mapped_Line (Sfile)));
1859 Write_Char (')');
1860 Write_Eol;
1861 end if;
1863 Current_Error_Source_File := Sfile;
1864 end if;
1866 if Errs or List_Pragmas_Mode then
1867 Output_Line_Number (Physical_To_Logical (L, Sfile));
1868 Line_Number_Output := True;
1869 end if;
1871 S := Line_Start (L, Sfile);
1873 loop
1874 C := Source_Text (Sfile) (S);
1875 exit when C = ASCII.LF or else C = ASCII.CR or else C = EOF;
1877 -- Deal with matching entry in List_Pragmas table
1879 if Full_List
1880 and then List_Pragmas_Index <= List_Pragmas.Last
1881 and then S = List_Pragmas.Table (List_Pragmas_Index).Ploc
1882 then
1883 case List_Pragmas.Table (List_Pragmas_Index).Ptyp is
1884 when Page =>
1885 Write_Char (C);
1887 -- Ignore if on line with errors so that error flags
1888 -- get properly listed with the error line .
1890 if not Errs then
1891 Write_Char (ASCII.FF);
1892 end if;
1894 when List_On =>
1895 List_Pragmas_Mode := True;
1897 if not Line_Number_Output then
1898 Output_Line_Number (Physical_To_Logical (L, Sfile));
1899 Line_Number_Output := True;
1900 end if;
1902 Write_Char (C);
1904 when List_Off =>
1905 Write_Char (C);
1906 List_Pragmas_Mode := False;
1907 end case;
1909 List_Pragmas_Index := List_Pragmas_Index + 1;
1911 -- Normal case (no matching entry in List_Pragmas table)
1913 else
1914 if Errs or List_Pragmas_Mode then
1915 Write_Char (C);
1916 end if;
1917 end if;
1919 S := S + 1;
1920 end loop;
1922 if Line_Number_Output then
1923 Write_Eol;
1924 end if;
1925 end Output_Source_Line;
1927 --------------------
1928 -- Purge_Messages --
1929 --------------------
1931 procedure Purge_Messages (From : Source_Ptr; To : Source_Ptr) is
1932 E : Error_Msg_Id;
1934 function To_Be_Purged (E : Error_Msg_Id) return Boolean;
1935 -- Returns True for a message that is to be purged. Also adjusts
1936 -- error counts appropriately.
1938 function To_Be_Purged (E : Error_Msg_Id) return Boolean is
1939 begin
1940 if E /= No_Error_Msg
1941 and then Errors.Table (E).Sptr > From
1942 and then Errors.Table (E).Sptr < To
1943 then
1944 if Errors.Table (E).Warn then
1945 Warnings_Detected := Warnings_Detected - 1;
1946 else
1947 Total_Errors_Detected := Total_Errors_Detected - 1;
1949 if Errors.Table (E).Serious then
1950 Serious_Errors_Detected := Serious_Errors_Detected - 1;
1951 end if;
1952 end if;
1954 return True;
1956 else
1957 return False;
1958 end if;
1959 end To_Be_Purged;
1961 -- Start of processing for Purge_Messages
1963 begin
1964 while To_Be_Purged (Error_Msgs) loop
1965 Error_Msgs := Errors.Table (Error_Msgs).Next;
1966 end loop;
1968 E := Error_Msgs;
1969 while E /= No_Error_Msg loop
1970 while To_Be_Purged (Errors.Table (E).Next) loop
1971 Errors.Table (E).Next :=
1972 Errors.Table (Errors.Table (E).Next).Next;
1973 end loop;
1975 E := Errors.Table (E).Next;
1976 end loop;
1977 end Purge_Messages;
1979 -----------------------------
1980 -- Remove_Warning_Messages --
1981 -----------------------------
1983 procedure Remove_Warning_Messages (N : Node_Id) is
1985 function Check_For_Warning (N : Node_Id) return Traverse_Result;
1986 -- This function checks one node for a possible warning message.
1988 function Check_All_Warnings is new
1989 Traverse_Func (Check_For_Warning);
1990 -- This defines the traversal operation
1992 -----------------------
1993 -- Check_For_Warning --
1994 -----------------------
1996 function Check_For_Warning (N : Node_Id) return Traverse_Result is
1997 Loc : constant Source_Ptr := Sloc (N);
1998 E : Error_Msg_Id;
2000 function To_Be_Removed (E : Error_Msg_Id) return Boolean;
2001 -- Returns True for a message that is to be removed. Also adjusts
2002 -- warning count appropriately.
2004 -------------------
2005 -- To_Be_Removed --
2006 -------------------
2008 function To_Be_Removed (E : Error_Msg_Id) return Boolean is
2009 begin
2010 if E /= No_Error_Msg
2011 and then Errors.Table (E).Fptr = Loc
2012 and then Errors.Table (E).Warn
2013 then
2014 Warnings_Detected := Warnings_Detected - 1;
2015 return True;
2016 else
2017 return False;
2018 end if;
2019 end To_Be_Removed;
2021 -- Start of processing for Check_For_Warnings
2023 begin
2024 while To_Be_Removed (Error_Msgs) loop
2025 Error_Msgs := Errors.Table (Error_Msgs).Next;
2026 end loop;
2028 E := Error_Msgs;
2029 while E /= No_Error_Msg loop
2030 while To_Be_Removed (Errors.Table (E).Next) loop
2031 Errors.Table (E).Next :=
2032 Errors.Table (Errors.Table (E).Next).Next;
2033 end loop;
2035 E := Errors.Table (E).Next;
2036 end loop;
2038 if Nkind (N) = N_Raise_Constraint_Error
2039 and then Original_Node (N) /= N
2040 and then No (Condition (N))
2041 then
2042 -- Warnings may have been posted on subexpressions of
2043 -- the original tree. We place the original node back
2044 -- on the tree to remove those warnings, whose sloc
2045 -- do not match those of any node in the current tree.
2046 -- Given that we are in unreachable code, this modification
2047 -- to the tree is harmless.
2049 declare
2050 Status : Traverse_Result;
2052 begin
2053 if Is_List_Member (N) then
2054 Set_Condition (N, Original_Node (N));
2055 Status := Check_All_Warnings (Condition (N));
2056 else
2057 Rewrite (N, Original_Node (N));
2058 Status := Check_All_Warnings (N);
2059 end if;
2061 return Status;
2062 end;
2064 else
2065 return OK;
2066 end if;
2067 end Check_For_Warning;
2069 -- Start of processing for Remove_Warning_Messages
2071 begin
2072 if Warnings_Detected /= 0 then
2073 declare
2074 Discard : Traverse_Result;
2075 begin
2076 Discard := Check_All_Warnings (N);
2077 end;
2078 end if;
2079 end Remove_Warning_Messages;
2081 ----------------
2082 -- Same_Error --
2083 ----------------
2085 function Same_Error (M1, M2 : Error_Msg_Id) return Boolean is
2086 Msg1 : constant String_Ptr := Errors.Table (M1).Text;
2087 Msg2 : constant String_Ptr := Errors.Table (M2).Text;
2089 Msg2_Len : constant Integer := Msg2'Length;
2090 Msg1_Len : constant Integer := Msg1'Length;
2092 begin
2093 return
2094 Msg1.all = Msg2.all
2095 or else
2096 (Msg1_Len - 10 > Msg2_Len
2097 and then
2098 Msg2.all = Msg1.all (1 .. Msg2_Len)
2099 and then
2100 Msg1 (Msg2_Len + 1 .. Msg2_Len + 10) = ", instance")
2101 or else
2102 (Msg2_Len - 10 > Msg1_Len
2103 and then
2104 Msg1.all = Msg2.all (1 .. Msg1_Len)
2105 and then
2106 Msg2 (Msg1_Len + 1 .. Msg1_Len + 10) = ", instance");
2107 end Same_Error;
2109 -------------------
2110 -- Set_Msg_Blank --
2111 -------------------
2113 procedure Set_Msg_Blank is
2114 begin
2115 if Msglen > 0
2116 and then Msg_Buffer (Msglen) /= ' '
2117 and then Msg_Buffer (Msglen) /= '('
2118 and then not Manual_Quote_Mode
2119 then
2120 Set_Msg_Char (' ');
2121 end if;
2122 end Set_Msg_Blank;
2124 -------------------------------
2125 -- Set_Msg_Blank_Conditional --
2126 -------------------------------
2128 procedure Set_Msg_Blank_Conditional is
2129 begin
2130 if Msglen > 0
2131 and then Msg_Buffer (Msglen) /= ' '
2132 and then Msg_Buffer (Msglen) /= '('
2133 and then Msg_Buffer (Msglen) /= '"'
2134 and then not Manual_Quote_Mode
2135 then
2136 Set_Msg_Char (' ');
2137 end if;
2138 end Set_Msg_Blank_Conditional;
2140 ------------------
2141 -- Set_Msg_Char --
2142 ------------------
2144 procedure Set_Msg_Char (C : Character) is
2145 begin
2147 -- The check for message buffer overflow is needed to deal with cases
2148 -- where insertions get too long (in particular a child unit name can
2149 -- be very long).
2151 if Msglen < Max_Msg_Length then
2152 Msglen := Msglen + 1;
2153 Msg_Buffer (Msglen) := C;
2154 end if;
2155 end Set_Msg_Char;
2157 ------------------------------
2158 -- Set_Msg_Insertion_Column --
2159 ------------------------------
2161 procedure Set_Msg_Insertion_Column is
2162 begin
2163 if Style.RM_Column_Check then
2164 Set_Msg_Str (" in column ");
2165 Set_Msg_Int (Int (Error_Msg_Col) + 1);
2166 end if;
2167 end Set_Msg_Insertion_Column;
2169 ---------------------------------
2170 -- Set_Msg_Insertion_File_Name --
2171 ---------------------------------
2173 procedure Set_Msg_Insertion_File_Name is
2174 begin
2175 if Error_Msg_Name_1 = No_Name then
2176 null;
2178 elsif Error_Msg_Name_1 = Error_Name then
2179 Set_Msg_Blank;
2180 Set_Msg_Str ("<error>");
2182 else
2183 Set_Msg_Blank;
2184 Get_Name_String (Error_Msg_Name_1);
2185 Set_Msg_Quote;
2186 Set_Msg_Name_Buffer;
2187 Set_Msg_Quote;
2188 end if;
2190 -- The following assignments ensure that the second and third percent
2191 -- insertion characters will correspond to the Error_Msg_Name_2 and
2192 -- Error_Msg_Name_3 as required.
2194 Error_Msg_Name_1 := Error_Msg_Name_2;
2195 Error_Msg_Name_2 := Error_Msg_Name_3;
2197 end Set_Msg_Insertion_File_Name;
2199 -----------------------------------
2200 -- Set_Msg_Insertion_Line_Number --
2201 -----------------------------------
2203 procedure Set_Msg_Insertion_Line_Number (Loc, Flag : Source_Ptr) is
2204 Sindex_Loc : Source_File_Index;
2205 Sindex_Flag : Source_File_Index;
2207 begin
2208 Set_Msg_Blank;
2210 if Loc = No_Location then
2211 Set_Msg_Str ("at unknown location");
2213 elsif Loc <= Standard_Location then
2214 Set_Msg_Str ("in package Standard");
2216 if Loc = Standard_ASCII_Location then
2217 Set_Msg_Str (".ASCII");
2218 end if;
2220 else
2221 -- Add "at file-name:" if reference is to other than the source
2222 -- file in which the error message is placed. Note that we check
2223 -- full file names, rather than just the source indexes, to
2224 -- deal with generic instantiations from the current file.
2226 Sindex_Loc := Get_Source_File_Index (Loc);
2227 Sindex_Flag := Get_Source_File_Index (Flag);
2229 if Full_File_Name (Sindex_Loc) /= Full_File_Name (Sindex_Flag) then
2230 Set_Msg_Str ("at ");
2231 Get_Name_String
2232 (Reference_Name (Get_Source_File_Index (Loc)));
2233 Set_Msg_Name_Buffer;
2234 Set_Msg_Char (':');
2236 -- If in current file, add text "at line "
2238 else
2239 Set_Msg_Str ("at line ");
2240 end if;
2242 -- Output line number for reference
2244 Set_Msg_Int (Int (Get_Logical_Line_Number (Loc)));
2246 -- Deal with the instantiation case. We may have a reference to,
2247 -- e.g. a type, that is declared within a generic template, and
2248 -- what we are really referring to is the occurrence in an instance.
2249 -- In this case, the line number of the instantiation is also of
2250 -- interest, and we add a notation:
2252 -- , instance at xxx
2254 -- where xxx is a line number output using this same routine (and
2255 -- the recursion can go further if the instantiation is itself in
2256 -- a generic template).
2258 -- The flag location passed to us in this situation is indeed the
2259 -- line number within the template, but as described in Sinput.L
2260 -- (file sinput-l.ads, section "Handling Generic Instantiations")
2261 -- we can retrieve the location of the instantiation itself from
2262 -- this flag location value.
2264 -- Note: this processing is suppressed if Suppress_Instance_Location
2265 -- is set True. This is used to prevent redundant annotations of the
2266 -- location of the instantiation in the case where we are placing
2267 -- the messages on the instantiation in any case.
2269 if Instantiation (Sindex_Loc) /= No_Location
2270 and then not Suppress_Instance_Location
2271 then
2272 Set_Msg_Str (", instance ");
2273 Set_Msg_Insertion_Line_Number (Instantiation (Sindex_Loc), Flag);
2274 end if;
2275 end if;
2276 end Set_Msg_Insertion_Line_Number;
2278 ----------------------------
2279 -- Set_Msg_Insertion_Name --
2280 ----------------------------
2282 procedure Set_Msg_Insertion_Name is
2283 begin
2284 if Error_Msg_Name_1 = No_Name then
2285 null;
2287 elsif Error_Msg_Name_1 = Error_Name then
2288 Set_Msg_Blank;
2289 Set_Msg_Str ("<error>");
2291 else
2292 Set_Msg_Blank_Conditional;
2293 Get_Unqualified_Decoded_Name_String (Error_Msg_Name_1);
2295 -- Remove %s or %b at end. These come from unit names. If the
2296 -- caller wanted the (unit) or (body), then they would have used
2297 -- the $ insertion character. Certainly no error message should
2298 -- ever have %b or %s explicitly occurring.
2300 if Name_Len > 2
2301 and then Name_Buffer (Name_Len - 1) = '%'
2302 and then (Name_Buffer (Name_Len) = 'b'
2303 or else
2304 Name_Buffer (Name_Len) = 's')
2305 then
2306 Name_Len := Name_Len - 2;
2307 end if;
2309 -- Remove upper case letter at end, again, we should not be getting
2310 -- such names, and what we hope is that the remainder makes sense.
2312 if Name_Len > 1
2313 and then Name_Buffer (Name_Len) in 'A' .. 'Z'
2314 then
2315 Name_Len := Name_Len - 1;
2316 end if;
2318 -- If operator name or character literal name, just print it as is
2319 -- Also print as is if it ends in a right paren (case of x'val(nnn))
2321 if Name_Buffer (1) = '"'
2322 or else Name_Buffer (1) = '''
2323 or else Name_Buffer (Name_Len) = ')'
2324 then
2325 Set_Msg_Name_Buffer;
2327 -- Else output with surrounding quotes in proper casing mode
2329 else
2330 Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case);
2331 Set_Msg_Quote;
2332 Set_Msg_Name_Buffer;
2333 Set_Msg_Quote;
2334 end if;
2335 end if;
2337 -- The following assignments ensure that the second and third percent
2338 -- insertion characters will correspond to the Error_Msg_Name_2 and
2339 -- Error_Msg_Name_3 as required.
2341 Error_Msg_Name_1 := Error_Msg_Name_2;
2342 Error_Msg_Name_2 := Error_Msg_Name_3;
2344 end Set_Msg_Insertion_Name;
2346 ----------------------------
2347 -- Set_Msg_Insertion_Node --
2348 ----------------------------
2350 procedure Set_Msg_Insertion_Node is
2351 begin
2352 Suppress_Message :=
2353 Error_Msg_Node_1 = Error
2354 or else Error_Msg_Node_1 = Any_Type;
2356 if Error_Msg_Node_1 = Empty then
2357 Set_Msg_Blank_Conditional;
2358 Set_Msg_Str ("<empty>");
2360 elsif Error_Msg_Node_1 = Error then
2361 Set_Msg_Blank;
2362 Set_Msg_Str ("<error>");
2364 elsif Error_Msg_Node_1 = Standard_Void_Type then
2365 Set_Msg_Blank;
2366 Set_Msg_Str ("procedure name");
2368 else
2369 Set_Msg_Blank_Conditional;
2371 -- Skip quotes for operator case
2373 if Nkind (Error_Msg_Node_1) in N_Op then
2374 Set_Msg_Node (Error_Msg_Node_1);
2376 else
2377 Set_Msg_Quote;
2378 Set_Qualification (Error_Msg_Qual_Level, Error_Msg_Node_1);
2379 Set_Msg_Node (Error_Msg_Node_1);
2380 Set_Msg_Quote;
2381 end if;
2382 end if;
2384 -- The following assignment ensures that a second ampersand insertion
2385 -- character will correspond to the Error_Msg_Node_2 parameter.
2387 Error_Msg_Node_1 := Error_Msg_Node_2;
2389 end Set_Msg_Insertion_Node;
2391 -------------------------------------
2392 -- Set_Msg_Insertion_Reserved_Name --
2393 -------------------------------------
2395 procedure Set_Msg_Insertion_Reserved_Name is
2396 begin
2397 Set_Msg_Blank_Conditional;
2398 Get_Name_String (Error_Msg_Name_1);
2399 Set_Msg_Quote;
2400 Set_Casing (Keyword_Casing (Flag_Source), All_Lower_Case);
2401 Set_Msg_Name_Buffer;
2402 Set_Msg_Quote;
2403 end Set_Msg_Insertion_Reserved_Name;
2405 -------------------------------------
2406 -- Set_Msg_Insertion_Reserved_Word --
2407 -------------------------------------
2409 procedure Set_Msg_Insertion_Reserved_Word
2410 (Text : String;
2411 J : in out Integer)
2413 begin
2414 Set_Msg_Blank_Conditional;
2415 Name_Len := 0;
2417 while J <= Text'Last and then Text (J) in 'A' .. 'Z' loop
2418 Name_Len := Name_Len + 1;
2419 Name_Buffer (Name_Len) := Text (J);
2420 J := J + 1;
2421 end loop;
2423 Set_Casing (Keyword_Casing (Flag_Source), All_Lower_Case);
2424 Set_Msg_Quote;
2425 Set_Msg_Name_Buffer;
2426 Set_Msg_Quote;
2427 end Set_Msg_Insertion_Reserved_Word;
2429 --------------------------------------
2430 -- Set_Msg_Insertion_Type_Reference --
2431 --------------------------------------
2433 procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr) is
2434 Ent : Entity_Id;
2436 begin
2437 Set_Msg_Blank;
2439 if Error_Msg_Node_1 = Standard_Void_Type then
2440 Set_Msg_Str ("package or procedure name");
2441 return;
2443 elsif Error_Msg_Node_1 = Standard_Exception_Type then
2444 Set_Msg_Str ("exception name");
2445 return;
2447 elsif Error_Msg_Node_1 = Any_Access
2448 or else Error_Msg_Node_1 = Any_Array
2449 or else Error_Msg_Node_1 = Any_Boolean
2450 or else Error_Msg_Node_1 = Any_Character
2451 or else Error_Msg_Node_1 = Any_Composite
2452 or else Error_Msg_Node_1 = Any_Discrete
2453 or else Error_Msg_Node_1 = Any_Fixed
2454 or else Error_Msg_Node_1 = Any_Integer
2455 or else Error_Msg_Node_1 = Any_Modular
2456 or else Error_Msg_Node_1 = Any_Numeric
2457 or else Error_Msg_Node_1 = Any_Real
2458 or else Error_Msg_Node_1 = Any_Scalar
2459 or else Error_Msg_Node_1 = Any_String
2460 then
2461 Get_Unqualified_Decoded_Name_String (Chars (Error_Msg_Node_1));
2462 Set_Msg_Name_Buffer;
2463 return;
2465 elsif Error_Msg_Node_1 = Universal_Real then
2466 Set_Msg_Str ("type universal real");
2467 return;
2469 elsif Error_Msg_Node_1 = Universal_Integer then
2470 Set_Msg_Str ("type universal integer");
2471 return;
2473 elsif Error_Msg_Node_1 = Universal_Fixed then
2474 Set_Msg_Str ("type universal fixed");
2475 return;
2476 end if;
2478 -- Special case of anonymous array
2480 if Nkind (Error_Msg_Node_1) in N_Entity
2481 and then Is_Array_Type (Error_Msg_Node_1)
2482 and then Present (Related_Array_Object (Error_Msg_Node_1))
2483 then
2484 Set_Msg_Str ("type of ");
2485 Set_Msg_Node (Related_Array_Object (Error_Msg_Node_1));
2486 Set_Msg_Str (" declared");
2487 Set_Msg_Insertion_Line_Number
2488 (Sloc (Related_Array_Object (Error_Msg_Node_1)), Flag);
2489 return;
2490 end if;
2492 -- If we fall through, it is not a special case, so first output
2493 -- the name of the type, preceded by private for a private type
2495 if Is_Private_Type (Error_Msg_Node_1) then
2496 Set_Msg_Str ("private type ");
2497 else
2498 Set_Msg_Str ("type ");
2499 end if;
2501 Ent := Error_Msg_Node_1;
2503 if Is_Internal_Name (Chars (Ent)) then
2504 Unwind_Internal_Type (Ent);
2505 end if;
2507 -- Types in Standard are displayed as "Standard.name"
2509 if Sloc (Ent) <= Standard_Location then
2510 Set_Msg_Quote;
2511 Set_Msg_Str ("Standard.");
2512 Set_Msg_Node (Ent);
2513 Add_Class;
2514 Set_Msg_Quote;
2516 -- Types in other language defined units are displayed as
2517 -- "package-name.type-name"
2519 elsif
2520 Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Ent)))
2521 then
2522 Get_Unqualified_Decoded_Name_String
2523 (Unit_Name (Get_Source_Unit (Ent)));
2524 Name_Len := Name_Len - 2;
2525 Set_Msg_Quote;
2526 Set_Casing (Mixed_Case);
2527 Set_Msg_Name_Buffer;
2528 Set_Msg_Char ('.');
2529 Set_Casing (Mixed_Case);
2530 Set_Msg_Node (Ent);
2531 Add_Class;
2532 Set_Msg_Quote;
2534 -- All other types display as "type name" defined at line xxx
2535 -- possibly qualified if qualification is requested.
2537 else
2538 Set_Msg_Quote;
2539 Set_Qualification (Error_Msg_Qual_Level, Ent);
2540 Set_Msg_Node (Ent);
2541 Add_Class;
2542 Set_Msg_Quote;
2543 end if;
2545 -- If the original type did not come from a predefined
2546 -- file, add the location where the type was defined.
2548 if Sloc (Error_Msg_Node_1) > Standard_Location
2549 and then
2550 not Is_Predefined_File_Name
2551 (Unit_File_Name (Get_Source_Unit (Error_Msg_Node_1)))
2552 then
2553 Set_Msg_Str (" defined");
2554 Set_Msg_Insertion_Line_Number (Sloc (Error_Msg_Node_1), Flag);
2556 -- If it did come from a predefined file, deal with the case where
2557 -- this was a file with a generic instantiation from elsewhere.
2559 else
2560 if Sloc (Error_Msg_Node_1) > Standard_Location then
2561 declare
2562 Iloc : constant Source_Ptr :=
2563 Instantiation_Location (Sloc (Error_Msg_Node_1));
2565 begin
2566 if Iloc /= No_Location
2567 and then not Suppress_Instance_Location
2568 then
2569 Set_Msg_Str (" from instance");
2570 Set_Msg_Insertion_Line_Number (Iloc, Flag);
2571 end if;
2572 end;
2573 end if;
2574 end if;
2576 end Set_Msg_Insertion_Type_Reference;
2578 ----------------------------
2579 -- Set_Msg_Insertion_Uint --
2580 ----------------------------
2582 procedure Set_Msg_Insertion_Uint is
2583 begin
2584 Set_Msg_Blank;
2585 UI_Image (Error_Msg_Uint_1);
2587 for J in 1 .. UI_Image_Length loop
2588 Set_Msg_Char (UI_Image_Buffer (J));
2589 end loop;
2591 -- The following assignment ensures that a second carret insertion
2592 -- character will correspond to the Error_Msg_Uint_2 parameter.
2594 Error_Msg_Uint_1 := Error_Msg_Uint_2;
2595 end Set_Msg_Insertion_Uint;
2597 ---------------------------------
2598 -- Set_Msg_Insertion_Unit_Name --
2599 ---------------------------------
2601 procedure Set_Msg_Insertion_Unit_Name is
2602 begin
2603 if Error_Msg_Unit_1 = No_Name then
2604 null;
2606 elsif Error_Msg_Unit_1 = Error_Name then
2607 Set_Msg_Blank;
2608 Set_Msg_Str ("<error>");
2610 else
2611 Get_Unit_Name_String (Error_Msg_Unit_1);
2612 Set_Msg_Blank;
2613 Set_Msg_Quote;
2614 Set_Msg_Name_Buffer;
2615 Set_Msg_Quote;
2616 end if;
2618 -- The following assignment ensures that a second percent insertion
2619 -- character will correspond to the Error_Msg_Unit_2 parameter.
2621 Error_Msg_Unit_1 := Error_Msg_Unit_2;
2623 end Set_Msg_Insertion_Unit_Name;
2625 -----------------
2626 -- Set_Msg_Int --
2627 -----------------
2629 procedure Set_Msg_Int (Line : Int) is
2630 begin
2631 if Line > 9 then
2632 Set_Msg_Int (Line / 10);
2633 end if;
2635 Set_Msg_Char (Character'Val (Character'Pos ('0') + (Line rem 10)));
2636 end Set_Msg_Int;
2638 -------------------------
2639 -- Set_Msg_Name_Buffer --
2640 -------------------------
2642 procedure Set_Msg_Name_Buffer is
2643 begin
2644 for J in 1 .. Name_Len loop
2645 Set_Msg_Char (Name_Buffer (J));
2646 end loop;
2647 end Set_Msg_Name_Buffer;
2649 ------------------
2650 -- Set_Msg_Node --
2651 ------------------
2653 procedure Set_Msg_Node (Node : Node_Id) is
2654 Ent : Entity_Id;
2655 Nam : Name_Id;
2657 begin
2658 if Nkind (Node) = N_Designator then
2659 Set_Msg_Node (Name (Node));
2660 Set_Msg_Char ('.');
2661 Set_Msg_Node (Identifier (Node));
2662 return;
2664 elsif Nkind (Node) = N_Defining_Program_Unit_Name then
2665 Set_Msg_Node (Name (Node));
2666 Set_Msg_Char ('.');
2667 Set_Msg_Node (Defining_Identifier (Node));
2668 return;
2670 elsif Nkind (Node) = N_Selected_Component then
2671 Set_Msg_Node (Prefix (Node));
2672 Set_Msg_Char ('.');
2673 Set_Msg_Node (Selector_Name (Node));
2674 return;
2675 end if;
2677 -- The only remaining possibilities are identifiers, defining
2678 -- identifiers, pragmas, and pragma argument associations, i.e.
2679 -- nodes that have a Chars field.
2681 -- Internal names generally represent something gone wrong. An exception
2682 -- is the case of internal type names, where we try to find a reasonable
2683 -- external representation for the external name
2685 if Is_Internal_Name (Chars (Node))
2686 and then
2687 ((Is_Entity_Name (Node)
2688 and then Present (Entity (Node))
2689 and then Is_Type (Entity (Node)))
2690 or else
2691 (Nkind (Node) = N_Defining_Identifier and then Is_Type (Node)))
2692 then
2693 if Nkind (Node) = N_Identifier then
2694 Ent := Entity (Node);
2695 else
2696 Ent := Node;
2697 end if;
2699 Unwind_Internal_Type (Ent);
2700 Nam := Chars (Ent);
2702 else
2703 Nam := Chars (Node);
2704 end if;
2706 -- At this stage, the name to output is in Nam
2708 Get_Unqualified_Decoded_Name_String (Nam);
2710 -- Remove trailing upper case letters from the name (useful for
2711 -- dealing with some cases of internal names.
2713 while Name_Len > 1 and then Name_Buffer (Name_Len) in 'A' .. 'Z' loop
2714 Name_Len := Name_Len - 1;
2715 end loop;
2717 -- If we have any of the names from standard that start with the
2718 -- characters "any " (e.g. Any_Type), then kill the message since
2719 -- almost certainly it is a junk cascaded message.
2721 if Name_Len > 4
2722 and then Name_Buffer (1 .. 4) = "any "
2723 then
2724 Kill_Message := True;
2725 end if;
2727 -- Now we have to set the proper case. If we have a source location
2728 -- then do a check to see if the name in the source is the same name
2729 -- as the name in the Names table, except for possible differences
2730 -- in case, which is the case when we can copy from the source.
2732 declare
2733 Src_Loc : constant Source_Ptr := Sloc (Error_Msg_Node_1);
2734 Sbuffer : Source_Buffer_Ptr;
2735 Ref_Ptr : Integer;
2736 Src_Ptr : Source_Ptr;
2738 begin
2739 Ref_Ptr := 1;
2740 Src_Ptr := Src_Loc;
2742 -- Determine if the reference we are dealing with corresponds
2743 -- to text at the point of the error reference. This will often
2744 -- be the case for simple identifier references, and is the case
2745 -- where we can copy the spelling from the source.
2747 if Src_Loc /= No_Location
2748 and then Src_Loc > Standard_Location
2749 then
2750 Sbuffer := Source_Text (Get_Source_File_Index (Src_Loc));
2752 while Ref_Ptr <= Name_Len loop
2753 exit when
2754 Fold_Lower (Sbuffer (Src_Ptr)) /=
2755 Fold_Lower (Name_Buffer (Ref_Ptr));
2756 Ref_Ptr := Ref_Ptr + 1;
2757 Src_Ptr := Src_Ptr + 1;
2758 end loop;
2759 end if;
2761 -- If we get through the loop without a mismatch, then output
2762 -- the name the way it is spelled in the source program
2764 if Ref_Ptr > Name_Len then
2765 Src_Ptr := Src_Loc;
2767 for J in 1 .. Name_Len loop
2768 Name_Buffer (J) := Sbuffer (Src_Ptr);
2769 Src_Ptr := Src_Ptr + 1;
2770 end loop;
2772 -- Otherwise set the casing using the default identifier casing
2774 else
2775 Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case);
2776 end if;
2777 end;
2779 Set_Msg_Name_Buffer;
2780 Add_Class;
2782 -- Add 'Class if class wide type
2784 if Class_Flag then
2785 Set_Msg_Char (''');
2786 Get_Name_String (Name_Class);
2787 Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case);
2788 Set_Msg_Name_Buffer;
2789 end if;
2790 end Set_Msg_Node;
2792 -------------------
2793 -- Set_Msg_Quote --
2794 -------------------
2796 procedure Set_Msg_Quote is
2797 begin
2798 if not Manual_Quote_Mode then
2799 Set_Msg_Char ('"');
2800 end if;
2801 end Set_Msg_Quote;
2803 -----------------
2804 -- Set_Msg_Str --
2805 -----------------
2807 procedure Set_Msg_Str (Text : String) is
2808 begin
2809 for J in Text'Range loop
2810 Set_Msg_Char (Text (J));
2811 end loop;
2812 end Set_Msg_Str;
2814 ------------------
2815 -- Set_Msg_Text --
2816 ------------------
2818 procedure Set_Msg_Text (Text : String; Flag : Source_Ptr) is
2819 C : Character; -- Current character
2820 P : Natural; -- Current index;
2822 begin
2823 Manual_Quote_Mode := False;
2824 Is_Unconditional_Msg := False;
2825 Msglen := 0;
2826 Flag_Source := Get_Source_File_Index (Flag);
2827 P := Text'First;
2829 while P <= Text'Last loop
2830 C := Text (P);
2831 P := P + 1;
2833 -- Check for insertion character
2835 if C = '%' then
2836 Set_Msg_Insertion_Name;
2838 elsif C = '$' then
2839 Set_Msg_Insertion_Unit_Name;
2841 elsif C = '{' then
2842 Set_Msg_Insertion_File_Name;
2844 elsif C = '}' then
2845 Set_Msg_Insertion_Type_Reference (Flag);
2847 elsif C = '*' then
2848 Set_Msg_Insertion_Reserved_Name;
2850 elsif C = '&' then
2851 Set_Msg_Insertion_Node;
2853 elsif C = '#' then
2854 Set_Msg_Insertion_Line_Number (Error_Msg_Sloc, Flag);
2856 elsif C = '\' then
2857 Continuation := True;
2859 elsif C = '@' then
2860 Set_Msg_Insertion_Column;
2862 elsif C = '^' then
2863 Set_Msg_Insertion_Uint;
2865 elsif C = '`' then
2866 Manual_Quote_Mode := not Manual_Quote_Mode;
2867 Set_Msg_Char ('"');
2869 elsif C = '!' then
2870 Is_Unconditional_Msg := True;
2872 elsif C = '?' then
2873 null;
2875 elsif C = '|' then
2876 null;
2878 elsif C = ''' then
2879 Set_Msg_Char (Text (P));
2880 P := P + 1;
2882 -- Upper case letter (start of reserved word if 2 or more)
2884 elsif C in 'A' .. 'Z'
2885 and then P <= Text'Last
2886 and then Text (P) in 'A' .. 'Z'
2887 then
2888 P := P - 1;
2889 Set_Msg_Insertion_Reserved_Word (Text, P);
2891 -- Normal character with no special treatment
2893 else
2894 Set_Msg_Char (C);
2895 end if;
2897 end loop;
2898 end Set_Msg_Text;
2900 ------------------------------
2901 -- Set_Next_Non_Deleted_Msg --
2902 ------------------------------
2904 procedure Set_Next_Non_Deleted_Msg (E : in out Error_Msg_Id) is
2905 begin
2906 if E = No_Error_Msg then
2907 return;
2909 else
2910 loop
2911 E := Errors.Table (E).Next;
2912 exit when E = No_Error_Msg or else not Errors.Table (E).Deleted;
2913 end loop;
2914 end if;
2915 end Set_Next_Non_Deleted_Msg;
2917 ----------------
2918 -- Set_Posted --
2919 ----------------
2921 procedure Set_Posted (N : Node_Id) is
2922 P : Node_Id;
2924 begin
2925 -- We always set Error_Posted on the node itself
2927 Set_Error_Posted (N);
2929 -- If it is a subexpression, then set Error_Posted on parents
2930 -- up to and including the first non-subexpression construct. This
2931 -- helps avoid cascaded error messages within a single expression.
2933 P := N;
2934 loop
2935 P := Parent (P);
2936 exit when No (P);
2937 Set_Error_Posted (P);
2938 exit when Nkind (P) not in N_Subexpr;
2939 end loop;
2941 -- A special check, if we just posted an error on an attribute
2942 -- definition clause, then also set the entity involved as posted.
2943 -- For example, this stops complaining about the alignment after
2944 -- complaining about the size, which is likely to be useless.
2946 if Nkind (P) = N_Attribute_Definition_Clause then
2947 if Is_Entity_Name (Name (P)) then
2948 Set_Error_Posted (Entity (Name (P)));
2949 end if;
2950 end if;
2951 end Set_Posted;
2953 -----------------------
2954 -- Set_Qualification --
2955 -----------------------
2957 procedure Set_Qualification (N : Nat; E : Entity_Id) is
2958 begin
2959 if N /= 0 and then Scope (E) /= Standard_Standard then
2960 Set_Qualification (N - 1, Scope (E));
2961 Set_Msg_Node (Scope (E));
2962 Set_Msg_Char ('.');
2963 end if;
2964 end Set_Qualification;
2966 ---------------------------
2967 -- Set_Warnings_Mode_Off --
2968 ---------------------------
2970 procedure Set_Warnings_Mode_Off (Loc : Source_Ptr) is
2971 begin
2972 -- Don't bother with entries from instantiation copies, since we
2973 -- will already have a copy in the template, which is what matters
2975 if Instantiation (Get_Source_File_Index (Loc)) /= No_Location then
2976 return;
2977 end if;
2979 -- If last entry in table already covers us, this is a redundant
2980 -- pragma Warnings (Off) and can be ignored. This also handles the
2981 -- case where all warnings are suppressed by command line switch.
2983 if Warnings.Last >= Warnings.First
2984 and then Warnings.Table (Warnings.Last).Start <= Loc
2985 and then Loc <= Warnings.Table (Warnings.Last).Stop
2986 then
2987 return;
2989 -- Otherwise establish a new entry, extending from the location of
2990 -- the pragma to the end of the current source file. This ending
2991 -- point will be adjusted by a subsequent pragma Warnings (On).
2993 else
2994 Warnings.Increment_Last;
2995 Warnings.Table (Warnings.Last).Start := Loc;
2996 Warnings.Table (Warnings.Last).Stop :=
2997 Source_Last (Current_Source_File);
2998 end if;
2999 end Set_Warnings_Mode_Off;
3001 --------------------------
3002 -- Set_Warnings_Mode_On --
3003 --------------------------
3005 procedure Set_Warnings_Mode_On (Loc : Source_Ptr) is
3006 begin
3007 -- Don't bother with entries from instantiation copies, since we
3008 -- will already have a copy in the template, which is what matters
3010 if Instantiation (Get_Source_File_Index (Loc)) /= No_Location then
3011 return;
3012 end if;
3014 -- Nothing to do unless command line switch to suppress all warnings
3015 -- is off, and the last entry in the warnings table covers this
3016 -- pragma Warnings (On), in which case adjust the end point.
3018 if (Warnings.Last >= Warnings.First
3019 and then Warnings.Table (Warnings.Last).Start <= Loc
3020 and then Loc <= Warnings.Table (Warnings.Last).Stop)
3021 and then Warning_Mode /= Suppress
3022 then
3023 Warnings.Table (Warnings.Last).Stop := Loc;
3024 end if;
3025 end Set_Warnings_Mode_On;
3027 ------------------------
3028 -- Special_Msg_Delete --
3029 ------------------------
3031 function Special_Msg_Delete
3032 (Msg : String;
3033 N : Node_Or_Entity_Id;
3034 E : Node_Or_Entity_Id)
3035 return Boolean
3037 begin
3038 -- Never delete messages in -gnatdO mode
3040 if Debug_Flag_OO then
3041 return False;
3043 -- When an atomic object refers to a non-atomic type in the same
3044 -- scope, we implicitly make the type atomic. In the non-error
3045 -- case this is surely safe (and in fact prevents an error from
3046 -- occurring if the type is not atomic by default). But if the
3047 -- object cannot be made atomic, then we introduce an extra junk
3048 -- message by this manipulation, which we get rid of here.
3050 -- We identify this case by the fact that it references a type for
3051 -- which Is_Atomic is set, but there is no Atomic pragma setting it.
3053 elsif Msg = "atomic access to & cannot be guaranteed"
3054 and then Is_Type (E)
3055 and then Is_Atomic (E)
3056 and then No (Get_Rep_Pragma (E, Name_Atomic))
3057 then
3058 return True;
3060 -- When a size is wrong for a frozen type there is no explicit
3061 -- size clause, and other errors have occurred, suppress the
3062 -- message, since it is likely that this size error is a cascaded
3063 -- result of other errors. The reason we eliminate unfrozen types
3064 -- is that messages issued before the freeze type are for sure OK.
3066 elsif Msg = "size for& too small, minimum allowed is ^"
3067 and then Is_Frozen (E)
3068 and then Serious_Errors_Detected > 0
3069 and then Nkind (N) /= N_Component_Clause
3070 and then Nkind (Parent (N)) /= N_Component_Clause
3071 and then
3072 No (Get_Attribute_Definition_Clause (E, Attribute_Size))
3073 and then
3074 No (Get_Attribute_Definition_Clause (E, Attribute_Object_Size))
3075 and then
3076 No (Get_Attribute_Definition_Clause (E, Attribute_Value_Size))
3077 then
3078 return True;
3080 -- All special tests complete, so go ahead with message
3082 else
3083 return False;
3084 end if;
3085 end Special_Msg_Delete;
3087 ------------------------------
3088 -- Test_Warning_Serious_Msg --
3089 ------------------------------
3091 procedure Test_Warning_Msg (Msg : String) is
3092 begin
3093 Is_Serious_Error := True;
3095 if Msg'Length > 7 and then Msg (1 .. 7) = "(style)" then
3096 Is_Warning_Msg := True;
3097 else
3098 Is_Warning_Msg := False;
3099 end if;
3101 for J in Msg'Range loop
3102 if Msg (J) = '?'
3103 and then (J = Msg'First or else Msg (J - 1) /= ''')
3104 then
3105 Is_Warning_Msg := True;
3107 elsif Msg (J) = '|'
3108 and then (J = Msg'First or else Msg (J - 1) /= ''')
3109 then
3110 Is_Serious_Error := False;
3111 end if;
3112 end loop;
3114 if Is_Warning_Msg then
3115 Is_Serious_Error := False;
3116 end if;
3117 end Test_Warning_Msg;
3119 --------------------------
3120 -- Unwind_Internal_Type --
3121 --------------------------
3123 procedure Unwind_Internal_Type (Ent : in out Entity_Id) is
3124 Derived : Boolean := False;
3125 Mchar : Character;
3126 Old_Ent : Entity_Id;
3128 begin
3129 -- Undo placement of a quote, since we will put it back later
3131 Mchar := Msg_Buffer (Msglen);
3133 if Mchar = '"' then
3134 Msglen := Msglen - 1;
3135 end if;
3137 -- The loop here deals with recursive types, we are trying to
3138 -- find a related entity that is not an implicit type. Note
3139 -- that the check with Old_Ent stops us from getting "stuck".
3140 -- Also, we don't output the "type derived from" message more
3141 -- than once in the case where we climb up multiple levels.
3143 loop
3144 Old_Ent := Ent;
3146 -- Implicit access type, use directly designated type
3148 if Is_Access_Type (Ent) then
3149 Set_Msg_Str ("access to ");
3150 Ent := Directly_Designated_Type (Ent);
3152 -- Classwide type
3154 elsif Is_Class_Wide_Type (Ent) then
3155 Class_Flag := True;
3156 Ent := Root_Type (Ent);
3158 -- Use base type if this is a subtype
3160 elsif Ent /= Base_Type (Ent) then
3161 Buffer_Remove ("type ");
3163 -- Avoid duplication "subtype of subtype of", and also replace
3164 -- "derived from subtype of" simply by "derived from"
3166 if not Buffer_Ends_With ("subtype of ")
3167 and then not Buffer_Ends_With ("derived from ")
3168 then
3169 Set_Msg_Str ("subtype of ");
3170 end if;
3172 Ent := Base_Type (Ent);
3174 -- If this is a base type with a first named subtype, use the
3175 -- first named subtype instead. This is not quite accurate in
3176 -- all cases, but it makes too much noise to be accurate and
3177 -- add 'Base in all cases. Note that we only do this is the
3178 -- first named subtype is not itself an internal name. This
3179 -- avoids the obvious loop (subtype->basetype->subtype) which
3180 -- would otherwise occur!)
3182 elsif Present (Freeze_Node (Ent))
3183 and then Present (First_Subtype_Link (Freeze_Node (Ent)))
3184 and then
3185 not Is_Internal_Name
3186 (Chars (First_Subtype_Link (Freeze_Node (Ent))))
3187 then
3188 Ent := First_Subtype_Link (Freeze_Node (Ent));
3190 -- Otherwise use root type
3192 else
3193 if not Derived then
3194 Buffer_Remove ("type ");
3196 -- Test for "subtype of type derived from" which seems
3197 -- excessive and is replaced by simply "type derived from"
3199 Buffer_Remove ("subtype of");
3201 -- Avoid duplication "type derived from type derived from"
3203 if not Buffer_Ends_With ("type derived from ") then
3204 Set_Msg_Str ("type derived from ");
3205 end if;
3207 Derived := True;
3208 end if;
3210 Ent := Etype (Ent);
3211 end if;
3213 -- If we are stuck in a loop, get out and settle for the internal
3214 -- name after all. In this case we set to kill the message if it
3215 -- is not the first error message (we really try hard not to show
3216 -- the dirty laundry of the implementation to the poor user!)
3218 if Ent = Old_Ent then
3219 Kill_Message := True;
3220 exit;
3221 end if;
3223 -- Get out if we finally found a non-internal name to use
3225 exit when not Is_Internal_Name (Chars (Ent));
3226 end loop;
3228 if Mchar = '"' then
3229 Set_Msg_Char ('"');
3230 end if;
3232 end Unwind_Internal_Type;
3234 -------------------------
3235 -- Warnings_Suppressed --
3236 -------------------------
3238 function Warnings_Suppressed (Loc : Source_Ptr) return Boolean is
3239 begin
3240 for J in Warnings.First .. Warnings.Last loop
3241 if Warnings.Table (J).Start <= Loc
3242 and then Loc <= Warnings.Table (J).Stop
3243 then
3244 return True;
3245 end if;
3246 end loop;
3248 return False;
3249 end Warnings_Suppressed;
3251 end Errout;