Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / ada / bcheck.adb
blob2ada0cf1353afae446bf6ea778d58ab845bcc2e3
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- B C H E C K --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2004 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 with ALI; use ALI;
28 with ALI.Util; use ALI.Util;
29 with Binderr; use Binderr;
30 with Butil; use Butil;
31 with Casing; use Casing;
32 with Fname; use Fname;
33 with Namet; use Namet;
34 with Opt; use Opt;
35 with Osint;
36 with Output; use Output;
37 with Rident; use Rident;
38 with Types; use Types;
40 package body Bcheck is
42 -----------------------
43 -- Local Subprograms --
44 -----------------------
46 -- The following checking subprograms make up the parts of the
47 -- configuration consistency check.
49 procedure Check_Consistent_Dynamic_Elaboration_Checking;
50 procedure Check_Consistent_Floating_Point_Format;
51 procedure Check_Consistent_Interrupt_States;
52 procedure Check_Consistent_Locking_Policy;
53 procedure Check_Consistent_Normalize_Scalars;
54 procedure Check_Consistent_Queuing_Policy;
55 procedure Check_Consistent_Restrictions;
56 procedure Check_Consistent_Zero_Cost_Exception_Handling;
58 procedure Consistency_Error_Msg (Msg : String);
59 -- Produce an error or a warning message, depending on whether an
60 -- inconsistent configuration is permitted or not.
62 function Same_Unit (U1 : Name_Id; U2 : Name_Id) return Boolean;
63 -- Used to compare two unit names for No_Dependence checks. U1 is in
64 -- standard unit name format, and U2 is in literal form with periods.
66 ------------------------------------
67 -- Check_Consistent_Configuration --
68 ------------------------------------
70 procedure Check_Configuration_Consistency is
71 begin
72 if Float_Format_Specified /= ' ' then
73 Check_Consistent_Floating_Point_Format;
74 end if;
76 if Queuing_Policy_Specified /= ' ' then
77 Check_Consistent_Queuing_Policy;
78 end if;
80 if Locking_Policy_Specified /= ' ' then
81 Check_Consistent_Locking_Policy;
82 end if;
84 if Zero_Cost_Exceptions_Specified then
85 Check_Consistent_Zero_Cost_Exception_Handling;
86 end if;
88 Check_Consistent_Normalize_Scalars;
89 Check_Consistent_Dynamic_Elaboration_Checking;
91 Check_Consistent_Restrictions;
92 Check_Consistent_Interrupt_States;
93 end Check_Configuration_Consistency;
95 ---------------------------------------------------
96 -- Check_Consistent_Dynamic_Elaboration_Checking --
97 ---------------------------------------------------
99 -- The rule here is that if a unit has dynamic elaboration checks,
100 -- then any unit it withs must meeting one of the following criteria:
102 -- 1. There is a pragma Elaborate_All for the with'ed unit
103 -- 2. The with'ed unit was compiled with dynamic elaboration checks
104 -- 3. The with'ed unit has pragma Preelaborate or Pure
105 -- 4. It is an internal GNAT unit (including children of GNAT)
107 procedure Check_Consistent_Dynamic_Elaboration_Checking is
108 begin
109 if Dynamic_Elaboration_Checks_Specified then
110 for U in First_Unit_Entry .. Units.Last loop
111 declare
112 UR : Unit_Record renames Units.Table (U);
114 begin
115 if UR.Dynamic_Elab then
116 for W in UR.First_With .. UR.Last_With loop
117 declare
118 WR : With_Record renames Withs.Table (W);
120 begin
121 if Get_Name_Table_Info (WR.Uname) /= 0 then
122 declare
123 WU : Unit_Record renames
124 Units.Table
125 (Unit_Id
126 (Get_Name_Table_Info (WR.Uname)));
128 begin
129 -- Case 1. Elaborate_All for with'ed unit
131 if WR.Elaborate_All then
132 null;
134 -- Case 2. With'ed unit has dynamic elab checks
136 elsif WU.Dynamic_Elab then
137 null;
139 -- Case 3. With'ed unit is Preelaborate or Pure
141 elsif WU.Preelab or WU.Pure then
142 null;
144 -- Case 4. With'ed unit is internal file
146 elsif Is_Internal_File_Name (WU.Sfile) then
147 null;
149 -- Issue warning, not one of the safe cases
151 else
152 Error_Msg_Name_1 := UR.Sfile;
153 Error_Msg
154 ("?% has dynamic elaboration checks " &
155 "and with's");
157 Error_Msg_Name_1 := WU.Sfile;
158 Error_Msg
159 ("? % which has static elaboration " &
160 "checks");
162 Warnings_Detected := Warnings_Detected - 1;
163 end if;
164 end;
165 end if;
166 end;
167 end loop;
168 end if;
169 end;
170 end loop;
171 end if;
172 end Check_Consistent_Dynamic_Elaboration_Checking;
174 --------------------------------------------
175 -- Check_Consistent_Floating_Point_Format --
176 --------------------------------------------
178 -- The rule is that all files must be compiled with the same setting
179 -- for the floating-point format.
181 procedure Check_Consistent_Floating_Point_Format is
182 begin
183 -- First search for a unit specifying a floating-point format and then
184 -- check all remaining units against it.
186 Find_Format : for A1 in ALIs.First .. ALIs.Last loop
187 if ALIs.Table (A1).Float_Format /= ' ' then
188 Check_Format : declare
189 Format : constant Character := ALIs.Table (A1).Float_Format;
190 begin
191 for A2 in A1 + 1 .. ALIs.Last loop
192 if ALIs.Table (A2).Float_Format /= Format then
193 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
194 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
196 Consistency_Error_Msg
197 ("% and % compiled with different " &
198 "floating-point representations");
199 exit Find_Format;
200 end if;
201 end loop;
202 end Check_Format;
204 exit Find_Format;
205 end if;
206 end loop Find_Format;
207 end Check_Consistent_Floating_Point_Format;
209 ---------------------------------------
210 -- Check_Consistent_Interrupt_States --
211 ---------------------------------------
213 -- The rule is that if the state of a given interrupt is specified
214 -- in more than one unit, it must be specified with a consistent state.
216 procedure Check_Consistent_Interrupt_States is
217 Max_Intrup : Nat;
219 begin
220 -- If no Interrupt_State entries, nothing to do
222 if Interrupt_States.Last < Interrupt_States.First then
223 return;
224 end if;
226 -- First find out the maximum interrupt value
228 Max_Intrup := 0;
229 for J in Interrupt_States.First .. Interrupt_States.Last loop
230 if Interrupt_States.Table (J).Interrupt_Id > Max_Intrup then
231 Max_Intrup := Interrupt_States.Table (J).Interrupt_Id;
232 end if;
233 end loop;
235 -- Now establish tables to be used for consistency checking
237 declare
238 Istate : array (0 .. Max_Intrup) of Character := (others => 'n');
239 -- Interrupt state entries, 'u'/'s'/'r' or 'n' to indicate an
240 -- entry that has not been set.
242 Afile : array (0 .. Max_Intrup) of ALI_Id;
243 -- ALI file that generated Istate entry for consistency message
245 Loc : array (0 .. Max_Intrup) of Nat;
246 -- Line numbers from IS pragma generating Istate entry
248 Inum : Nat;
249 -- Interrupt number from entry being tested
251 Stat : Character;
252 -- Interrupt state from entry being tested
254 Lnum : Nat;
255 -- Line number from entry being tested
257 begin
258 for F in ALIs.First .. ALIs.Last loop
259 for K in ALIs.Table (F).First_Interrupt_State ..
260 ALIs.Table (F).Last_Interrupt_State
261 loop
262 Inum := Interrupt_States.Table (K).Interrupt_Id;
263 Stat := Interrupt_States.Table (K).Interrupt_State;
264 Lnum := Interrupt_States.Table (K).IS_Pragma_Line;
266 if Istate (Inum) = 'n' then
267 Istate (Inum) := Stat;
268 Afile (Inum) := F;
269 Loc (Inum) := Lnum;
271 elsif Istate (Inum) /= Stat then
272 Error_Msg_Name_1 := ALIs.Table (Afile (Inum)).Sfile;
273 Error_Msg_Name_2 := ALIs.Table (F).Sfile;
274 Error_Msg_Nat_1 := Loc (Inum);
275 Error_Msg_Nat_2 := Lnum;
277 Consistency_Error_Msg
278 ("inconsistent interrupt states at %:# and %:#");
279 end if;
280 end loop;
281 end loop;
282 end;
283 end Check_Consistent_Interrupt_States;
285 -------------------------------------
286 -- Check_Consistent_Locking_Policy --
287 -------------------------------------
289 -- The rule is that all files for which the locking policy is
290 -- significant must be compiled with the same setting.
292 procedure Check_Consistent_Locking_Policy is
293 begin
294 -- First search for a unit specifying a policy and then
295 -- check all remaining units against it.
297 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
298 if ALIs.Table (A1).Locking_Policy /= ' ' then
299 Check_Policy : declare
300 Policy : constant Character := ALIs.Table (A1).Locking_Policy;
302 begin
303 for A2 in A1 + 1 .. ALIs.Last loop
304 if ALIs.Table (A2).Locking_Policy /= ' ' and
305 ALIs.Table (A2).Locking_Policy /= Policy
306 then
307 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
308 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
310 Consistency_Error_Msg
311 ("% and % compiled with different locking policies");
312 exit Find_Policy;
313 end if;
314 end loop;
315 end Check_Policy;
317 exit Find_Policy;
318 end if;
319 end loop Find_Policy;
320 end Check_Consistent_Locking_Policy;
322 ----------------------------------------
323 -- Check_Consistent_Normalize_Scalars --
324 ----------------------------------------
326 -- The rule is that if any unit is compiled with Normalized_Scalars,
327 -- then all other units in the partition must also be compiled with
328 -- Normalized_Scalars in effect.
330 -- There is some issue as to whether this consistency check is
331 -- desirable, it is certainly required at the moment by the RM.
332 -- We should keep a watch on the ARG and HRG deliberations here.
333 -- GNAT no longer depends on this consistency (it used to do so,
334 -- but that has been corrected in the latest version, since the
335 -- Initialize_Scalars pragma does not require consistency.
337 procedure Check_Consistent_Normalize_Scalars is
338 begin
339 if Normalize_Scalars_Specified and No_Normalize_Scalars_Specified then
340 Consistency_Error_Msg
341 ("some but not all files compiled with Normalize_Scalars");
343 Write_Eol;
344 Write_Str ("files compiled with Normalize_Scalars");
345 Write_Eol;
347 for A1 in ALIs.First .. ALIs.Last loop
348 if ALIs.Table (A1).Normalize_Scalars then
349 Write_Str (" ");
350 Write_Name (ALIs.Table (A1).Sfile);
351 Write_Eol;
352 end if;
353 end loop;
355 Write_Eol;
356 Write_Str ("files compiled without Normalize_Scalars");
357 Write_Eol;
359 for A1 in ALIs.First .. ALIs.Last loop
360 if not ALIs.Table (A1).Normalize_Scalars then
361 Write_Str (" ");
362 Write_Name (ALIs.Table (A1).Sfile);
363 Write_Eol;
364 end if;
365 end loop;
366 end if;
367 end Check_Consistent_Normalize_Scalars;
369 -------------------------------------
370 -- Check_Consistent_Queuing_Policy --
371 -------------------------------------
373 -- The rule is that all files for which the queuing policy is
374 -- significant must be compiled with the same setting.
376 procedure Check_Consistent_Queuing_Policy is
377 begin
378 -- First search for a unit specifying a policy and then
379 -- check all remaining units against it.
381 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
382 if ALIs.Table (A1).Queuing_Policy /= ' ' then
383 Check_Policy : declare
384 Policy : constant Character := ALIs.Table (A1).Queuing_Policy;
385 begin
386 for A2 in A1 + 1 .. ALIs.Last loop
387 if ALIs.Table (A2).Queuing_Policy /= ' '
388 and then
389 ALIs.Table (A2).Queuing_Policy /= Policy
390 then
391 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
392 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
394 Consistency_Error_Msg
395 ("% and % compiled with different queuing policies");
396 exit Find_Policy;
397 end if;
398 end loop;
399 end Check_Policy;
401 exit Find_Policy;
402 end if;
403 end loop Find_Policy;
404 end Check_Consistent_Queuing_Policy;
406 -----------------------------------
407 -- Check_Consistent_Restrictions --
408 -----------------------------------
410 -- The rule is that if a restriction is specified in any unit,
411 -- then all units must obey the restriction. The check applies
412 -- only to restrictions which require partition wide consistency,
413 -- and not to internal units.
415 procedure Check_Consistent_Restrictions is
416 Restriction_File_Output : Boolean;
417 -- Shows if we have output header messages for restriction violation
419 procedure Print_Restriction_File (R : All_Restrictions);
420 -- Print header line for R if not printed yet
422 ----------------------------
423 -- Print_Restriction_File --
424 ----------------------------
426 procedure Print_Restriction_File (R : All_Restrictions) is
427 begin
428 if not Restriction_File_Output then
429 Restriction_File_Output := True;
431 -- Find an ali file specifying the restriction
433 for A in ALIs.First .. ALIs.Last loop
434 if ALIs.Table (A).Restrictions.Set (R)
435 and then (R in All_Boolean_Restrictions
436 or else ALIs.Table (A).Restrictions.Value (R) =
437 Cumulative_Restrictions.Value (R))
438 then
439 -- We have found that ALI file A specifies the restriction
440 -- that is being violated (the minimum value is specified
441 -- in the case of a parameter restriction).
443 declare
444 M1 : constant String := "% has restriction ";
445 S : constant String := Restriction_Id'Image (R);
446 M2 : String (1 .. 200); -- big enough!
447 P : Integer;
449 begin
450 Name_Buffer (1 .. S'Length) := S;
451 Name_Len := S'Length;
452 Set_Casing (Mixed_Case);
454 M2 (M1'Range) := M1;
455 P := M1'Length + 1;
456 M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
457 P := P + S'Length;
459 if R in All_Parameter_Restrictions then
460 M2 (P .. P + 4) := " => #";
461 Error_Msg_Nat_1 :=
462 Int (Cumulative_Restrictions.Value (R));
463 P := P + 5;
464 end if;
466 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
467 Consistency_Error_Msg (M2 (1 .. P - 1));
468 Consistency_Error_Msg
469 ("but the following files violate this restriction:");
470 return;
471 end;
472 end if;
473 end loop;
474 end if;
475 end Print_Restriction_File;
477 -- Start of processing for Check_Consistent_Restrictions
479 begin
480 -- Loop through all restriction violations
482 for R in All_Restrictions loop
484 -- Check for violation of this restriction
486 if Cumulative_Restrictions.Set (R)
487 and then Cumulative_Restrictions.Violated (R)
488 and then (R in Partition_Boolean_Restrictions
489 or else (R in All_Parameter_Restrictions
490 and then
491 Cumulative_Restrictions.Count (R) >
492 Cumulative_Restrictions.Value (R)))
493 then
494 Restriction_File_Output := False;
496 -- Loop through files looking for violators
498 for A2 in ALIs.First .. ALIs.Last loop
499 declare
500 T : ALIs_Record renames ALIs.Table (A2);
502 begin
503 if T.Restrictions.Violated (R) then
505 -- We exclude predefined files from the list of
506 -- violators. This should be rethought. It is not
507 -- clear that this is the right thing to do, that
508 -- is particularly the case for restricted runtimes.
510 if not Is_Internal_File_Name (T.Sfile) then
512 -- Case of Boolean restriction, just print file name
514 if R in All_Boolean_Restrictions then
515 Print_Restriction_File (R);
516 Error_Msg_Name_1 := T.Sfile;
517 Consistency_Error_Msg (" %");
519 -- Case of Parameter restriction where violation
520 -- count exceeds restriction value, print file
521 -- name and count, adding "at least" if the
522 -- exact count is not known.
524 elsif R in Checked_Add_Parameter_Restrictions
525 or else T.Restrictions.Count (R) >
526 Cumulative_Restrictions.Value (R)
527 then
528 Print_Restriction_File (R);
529 Error_Msg_Name_1 := T.Sfile;
530 Error_Msg_Nat_1 := Int (T.Restrictions.Count (R));
532 if T.Restrictions.Unknown (R) then
533 Consistency_Error_Msg
534 (" % (count = at least #)");
535 else
536 Consistency_Error_Msg
537 (" % (count = #)");
538 end if;
539 end if;
540 end if;
541 end if;
542 end;
543 end loop;
544 end if;
545 end loop;
547 -- Now deal with No_Dependence indications. Note that we put the loop
548 -- through entries in the no dependency table first, since this loop
549 -- is most often empty (no such pragma Restrictions in use).
551 for ND in No_Deps.First .. No_Deps.Last loop
552 declare
553 ND_Unit : constant Name_Id := No_Deps.Table (ND).No_Dep_Unit;
555 begin
556 for J in ALIs.First .. ALIs.Last loop
557 declare
558 A : ALIs_Record renames ALIs.Table (J);
560 begin
561 for K in A.First_Unit .. A.Last_Unit loop
562 declare
563 U : Unit_Record renames Units.Table (K);
564 begin
565 for L in U.First_With .. U.Last_With loop
566 if Same_Unit (Withs.Table (L).Uname, ND_Unit) then
567 Error_Msg_Name_1 := U.Uname;
568 Error_Msg_Name_2 := ND_Unit;
569 Consistency_Error_Msg
570 ("unit & violates restriction " &
571 "No_Dependence => %");
572 end if;
573 end loop;
574 end;
575 end loop;
576 end;
577 end loop;
578 end;
579 end loop;
580 end Check_Consistent_Restrictions;
582 ---------------
583 -- Same_Unit --
584 ---------------
586 function Same_Unit (U1 : Name_Id; U2 : Name_Id) return Boolean is
587 begin
588 -- Note, the string U1 has a terminating %s or %b, U2 does not
590 if Length_Of_Name (U1) - 2 = Length_Of_Name (U2) then
591 Get_Name_String (U1);
593 declare
594 U1_Str : constant String := Name_Buffer (1 .. Name_Len - 2);
595 begin
596 Get_Name_String (U2);
597 return U1_Str = Name_Buffer (1 .. Name_Len);
598 end;
600 else
601 return False;
602 end if;
603 end Same_Unit;
605 ---------------------------------------------------
606 -- Check_Consistent_Zero_Cost_Exception_Handling --
607 ---------------------------------------------------
609 -- Check consistent zero cost exception handling. The rule is that
610 -- all units must have the same exception handling mechanism.
612 procedure Check_Consistent_Zero_Cost_Exception_Handling is
613 begin
614 Check_Mechanism : for A1 in ALIs.First + 1 .. ALIs.Last loop
615 if ALIs.Table (A1).Zero_Cost_Exceptions /=
616 ALIs.Table (ALIs.First).Zero_Cost_Exceptions
618 then
619 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
620 Error_Msg_Name_2 := ALIs.Table (ALIs.First).Sfile;
622 Consistency_Error_Msg ("% and % compiled with different "
623 & "exception handling mechanisms");
624 end if;
625 end loop Check_Mechanism;
626 end Check_Consistent_Zero_Cost_Exception_Handling;
628 -----------------------
629 -- Check_Consistency --
630 -----------------------
632 procedure Check_Consistency is
633 Src : Source_Id;
634 -- Source file Id for this Sdep entry
636 ALI_Path_Id : Name_Id;
638 begin
639 -- First, we go through the source table to see if there are any cases
640 -- in which we should go after source files and compute checksums of
641 -- the source files. We need to do this for any file for which we have
642 -- mismatching time stamps and (so far) matching checksums.
644 for S in Source.First .. Source.Last loop
646 -- If all time stamps for a file match, then there is nothing to
647 -- do, since we will not be checking checksums in that case anyway
649 if Source.Table (S).All_Timestamps_Match then
650 null;
652 -- If we did not find the source file, then we can't compute its
653 -- checksum anyway. Note that when we have a time stamp mismatch,
654 -- we try to find the source file unconditionally (i.e. if
655 -- Check_Source_Files is False).
657 elsif not Source.Table (S).Source_Found then
658 null;
660 -- If we already have non-matching or missing checksums, then no
661 -- need to try going after source file, since we won't trust the
662 -- checksums in any case.
664 elsif not Source.Table (S).All_Checksums_Match then
665 null;
667 -- Now we have the case where we have time stamp mismatches, and
668 -- the source file is around, but so far all checksums match. This
669 -- is the case where we need to compute the checksum from the source
670 -- file, since otherwise we would ignore the time stamp mismatches,
671 -- and that is wrong if the checksum of the source does not agree
672 -- with the checksums in the ALI files.
674 elsif Check_Source_Files then
675 if not Checksums_Match
676 (Source.Table (S).Checksum,
677 Get_File_Checksum (Source.Table (S).Sfile))
678 then
679 Source.Table (S).All_Checksums_Match := False;
680 end if;
681 end if;
682 end loop;
684 -- Loop through ALI files
686 ALIs_Loop : for A in ALIs.First .. ALIs.Last loop
688 -- Loop through Sdep entries in one ALI file
690 Sdep_Loop : for D in
691 ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
692 loop
693 if Sdep.Table (D).Dummy_Entry then
694 goto Continue;
695 end if;
697 Src := Source_Id (Get_Name_Table_Info (Sdep.Table (D).Sfile));
699 -- If the time stamps match, or all checksums match, then we
700 -- are OK, otherwise we have a definite error.
702 if Sdep.Table (D).Stamp /= Source.Table (Src).Stamp
703 and then not Source.Table (Src).All_Checksums_Match
704 then
705 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
706 Error_Msg_Name_2 := Sdep.Table (D).Sfile;
708 -- Two styles of message, depending on whether or not
709 -- the updated file is the one that must be recompiled
711 if Error_Msg_Name_1 = Error_Msg_Name_2 then
712 if Tolerate_Consistency_Errors then
713 Error_Msg
714 ("?% has been modified and should be recompiled");
715 else
716 Error_Msg
717 ("% has been modified and must be recompiled");
718 end if;
720 else
721 ALI_Path_Id :=
722 Osint.Find_File ((ALIs.Table (A).Afile), Osint.Library);
723 if Osint.Is_Readonly_Library (ALI_Path_Id) then
724 if Tolerate_Consistency_Errors then
725 Error_Msg ("?% should be recompiled");
726 Error_Msg_Name_1 := ALI_Path_Id;
727 Error_Msg ("?(% is obsolete and read-only)");
729 else
730 Error_Msg ("% must be compiled");
731 Error_Msg_Name_1 := ALI_Path_Id;
732 Error_Msg ("(% is obsolete and read-only)");
733 end if;
735 elsif Tolerate_Consistency_Errors then
736 Error_Msg
737 ("?% should be recompiled (% has been modified)");
739 else
740 Error_Msg ("% must be recompiled (% has been modified)");
741 end if;
742 end if;
744 if (not Tolerate_Consistency_Errors) and Verbose_Mode then
745 declare
746 Msg : constant String := "% time stamp ";
747 Buf : String (1 .. Msg'Length + Time_Stamp_Length);
749 begin
750 Buf (1 .. Msg'Length) := Msg;
751 Buf (Msg'Length + 1 .. Buf'Length) :=
752 String (Source.Table (Src).Stamp);
753 Error_Msg_Name_1 := Sdep.Table (D).Sfile;
754 Error_Msg (Buf);
755 end;
757 declare
758 Msg : constant String := " conflicts with % timestamp ";
759 Buf : String (1 .. Msg'Length + Time_Stamp_Length);
761 begin
762 Buf (1 .. Msg'Length) := Msg;
763 Buf (Msg'Length + 1 .. Buf'Length) :=
764 String (Sdep.Table (D).Stamp);
765 Error_Msg_Name_1 := Sdep.Table (D).Sfile;
766 Error_Msg (Buf);
767 end;
768 end if;
770 -- Exit from the loop through Sdep entries once we find one
771 -- that does not match.
773 exit Sdep_Loop;
774 end if;
776 <<Continue>>
777 null;
778 end loop Sdep_Loop;
779 end loop ALIs_Loop;
780 end Check_Consistency;
782 -------------------------------
783 -- Check_Duplicated_Subunits --
784 -------------------------------
786 procedure Check_Duplicated_Subunits is
787 begin
788 for J in Sdep.First .. Sdep.Last loop
789 if Sdep.Table (J).Subunit_Name /= No_Name then
790 Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
791 Name_Len := Name_Len + 2;
792 Name_Buffer (Name_Len - 1) := '%';
794 -- See if there is a body or spec with the same name
796 for K in Boolean loop
797 if K then
798 Name_Buffer (Name_Len) := 'b';
800 else
801 Name_Buffer (Name_Len) := 's';
802 end if;
804 declare
805 Info : constant Int := Get_Name_Table_Info (Name_Find);
807 begin
808 if Info /= 0 then
809 Set_Standard_Error;
810 Write_Str ("error: subunit """);
811 Write_Name_Decoded (Sdep.Table (J).Subunit_Name);
812 Write_Str (""" in file """);
813 Write_Name_Decoded (Sdep.Table (J).Sfile);
814 Write_Char ('"');
815 Write_Eol;
816 Write_Str (" has same name as unit """);
817 Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname);
818 Write_Str (""" found in file """);
819 Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile);
820 Write_Char ('"');
821 Write_Eol;
822 Write_Str (" this is not allowed within a single "
823 & "partition (RM 10.2(19))");
824 Write_Eol;
825 Osint.Exit_Program (Osint.E_Fatal);
826 end if;
827 end;
828 end loop;
829 end if;
830 end loop;
831 end Check_Duplicated_Subunits;
833 --------------------
834 -- Check_Versions --
835 --------------------
837 procedure Check_Versions is
838 VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;
840 begin
841 for A in ALIs.First .. ALIs.Last loop
842 if ALIs.Table (A).Ver_Len /= VL
843 or else ALIs.Table (A).Ver (1 .. VL) /=
844 ALIs.Table (ALIs.First).Ver (1 .. VL)
845 then
846 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
847 Error_Msg_Name_2 := ALIs.Table (ALIs.First).Sfile;
849 Consistency_Error_Msg
850 ("% and % compiled with different GNAT versions");
851 end if;
852 end loop;
853 end Check_Versions;
855 ---------------------------
856 -- Consistency_Error_Msg --
857 ---------------------------
859 procedure Consistency_Error_Msg (Msg : String) is
860 begin
861 if Tolerate_Consistency_Errors then
863 -- If consistency errors are tolerated,
864 -- output the message as a warning.
866 declare
867 Warning_Msg : String (1 .. Msg'Length + 1);
869 begin
870 Warning_Msg (1) := '?';
871 Warning_Msg (2 .. Warning_Msg'Last) := Msg;
873 Error_Msg (Warning_Msg);
874 end;
876 -- Otherwise the consistency error is a true error
878 else
879 Error_Msg (Msg);
880 end if;
881 end Consistency_Error_Msg;
883 end Bcheck;