Typo in last patch.
[official-gcc.git] / gcc / ada / prj-proc.adb
blob9d034a12dc52a58858d7489c41a9cbd40f623c78
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . P R O C --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-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 Err_Vars; use Err_Vars;
28 with Namet; use Namet;
29 with Opt;
30 with Osint; use Osint;
31 with Output; use Output;
32 with Prj.Attr; use Prj.Attr;
33 with Prj.Com; use Prj.Com;
34 with Prj.Err; use Prj.Err;
35 with Prj.Ext; use Prj.Ext;
36 with Prj.Nmsc; use Prj.Nmsc;
37 with Snames;
39 with GNAT.Case_Util; use GNAT.Case_Util;
40 with GNAT.HTable;
42 package body Prj.Proc is
44 Error_Report : Put_Line_Access := null;
46 package Processed_Projects is new GNAT.HTable.Simple_HTable
47 (Header_Num => Header_Num,
48 Element => Project_Id,
49 No_Element => No_Project,
50 Key => Name_Id,
51 Hash => Hash,
52 Equal => "=");
53 -- This hash table contains all processed projects
55 procedure Add (To_Exp : in out Name_Id; Str : Name_Id);
56 -- Concatenate two strings and returns another string if both
57 -- arguments are not null string.
59 procedure Add_Attributes
60 (Project : Project_Id;
61 Decl : in out Declarations;
62 First : Attribute_Node_Id);
63 -- Add all attributes, starting with First, with their default
64 -- values to the package or project with declarations Decl.
66 function Expression
67 (Project : Project_Id;
68 From_Project_Node : Project_Node_Id;
69 Pkg : Package_Id;
70 First_Term : Project_Node_Id;
71 Kind : Variable_Kind) return Variable_Value;
72 -- From N_Expression project node From_Project_Node, compute the value
73 -- of an expression and return it as a Variable_Value.
75 function Imported_Or_Extended_Project_From
76 (Project : Project_Id;
77 With_Name : Name_Id) return Project_Id;
78 -- Find an imported or extended project of Project whose name is With_Name
80 function Package_From
81 (Project : Project_Id;
82 With_Name : Name_Id) return Package_Id;
83 -- Find the package of Project whose name is With_Name
85 procedure Process_Declarative_Items
86 (Project : Project_Id;
87 From_Project_Node : Project_Node_Id;
88 Pkg : Package_Id;
89 Item : Project_Node_Id);
90 -- Process declarative items starting with From_Project_Node, and put them
91 -- in declarations Decl. This is a recursive procedure; it calls itself for
92 -- a package declaration or a case construction.
94 procedure Recursive_Process
95 (Project : out Project_Id;
96 From_Project_Node : Project_Node_Id;
97 Extended_By : Project_Id);
98 -- Process project with node From_Project_Node in the tree.
99 -- Do nothing if From_Project_Node is Empty_Node.
100 -- If project has already been processed, simply return its project id.
101 -- Otherwise create a new project id, mark it as processed, call itself
102 -- recursively for all imported projects and a extended project, if any.
103 -- Then process the declarative items of the project.
105 procedure Check
106 (Project : in out Project_Id;
107 Process_Languages : Languages_Processed;
108 Follow_Links : Boolean);
109 -- Set all projects to not checked, then call Recursive_Check for the
110 -- main project Project. Project is set to No_Project if errors occurred.
111 -- See Prj.Nmsc.Ada_Check for information on Follow_Links.
113 procedure Recursive_Check
114 (Project : Project_Id;
115 Process_Languages : Languages_Processed;
116 Follow_Links : Boolean);
117 -- If Project is not marked as checked, mark it as checked, call
118 -- Check_Naming_Scheme for the project, then call itself for a
119 -- possible extended project and all the imported projects of Project.
120 -- See Prj.Nmsc.Ada_Check for information on Follow_Links
122 ---------
123 -- Add --
124 ---------
126 procedure Add (To_Exp : in out Name_Id; Str : Name_Id) is
127 begin
128 if To_Exp = Types.No_Name or else To_Exp = Empty_String then
130 -- To_Exp is nil or empty. The result is Str.
132 To_Exp := Str;
134 -- If Str is nil, then do not change To_Ext
136 elsif Str /= No_Name and then Str /= Empty_String then
137 declare
138 S : constant String := Get_Name_String (Str);
140 begin
141 Get_Name_String (To_Exp);
142 Add_Str_To_Name_Buffer (S);
143 To_Exp := Name_Find;
144 end;
145 end if;
146 end Add;
148 --------------------
149 -- Add_Attributes --
150 --------------------
152 procedure Add_Attributes
153 (Project : Project_Id;
154 Decl : in out Declarations;
155 First : Attribute_Node_Id)
157 The_Attribute : Attribute_Node_Id := First;
158 Attribute_Data : Attribute_Record;
160 begin
161 while The_Attribute /= Empty_Attribute loop
162 Attribute_Data := Attributes.Table (The_Attribute);
164 if Attribute_Data.Kind_2 = Single then
165 declare
166 New_Attribute : Variable_Value;
168 begin
169 case Attribute_Data.Kind_1 is
171 -- Undefined should not happen
173 when Undefined =>
174 pragma Assert
175 (False, "attribute with an undefined kind");
176 raise Program_Error;
178 -- Single attributes have a default value of empty string
180 when Single =>
181 New_Attribute :=
182 (Project => Project,
183 Kind => Single,
184 Location => No_Location,
185 Default => True,
186 Value => Empty_String,
187 Index => 0);
189 -- List attributes have a default value of nil list
191 when List =>
192 New_Attribute :=
193 (Project => Project,
194 Kind => List,
195 Location => No_Location,
196 Default => True,
197 Values => Nil_String);
199 end case;
201 Variable_Elements.Increment_Last;
202 Variable_Elements.Table (Variable_Elements.Last) :=
203 (Next => Decl.Attributes,
204 Name => Attribute_Data.Name,
205 Value => New_Attribute);
206 Decl.Attributes := Variable_Elements.Last;
207 end;
208 end if;
210 The_Attribute := Attributes.Table (The_Attribute).Next;
211 end loop;
212 end Add_Attributes;
214 -----------
215 -- Check --
216 -----------
218 procedure Check
219 (Project : in out Project_Id;
220 Process_Languages : Languages_Processed;
221 Follow_Links : Boolean) is
222 begin
223 -- Make sure that all projects are marked as not checked
225 for Index in 1 .. Projects.Last loop
226 Projects.Table (Index).Checked := False;
227 end loop;
229 Recursive_Check (Project, Process_Languages, Follow_Links);
231 end Check;
233 ----------------
234 -- Expression --
235 ----------------
237 function Expression
238 (Project : Project_Id;
239 From_Project_Node : Project_Node_Id;
240 Pkg : Package_Id;
241 First_Term : Project_Node_Id;
242 Kind : Variable_Kind) return Variable_Value
244 The_Term : Project_Node_Id := First_Term;
245 -- The term in the expression list
247 The_Current_Term : Project_Node_Id := Empty_Node;
248 -- The current term node id
250 Result : Variable_Value (Kind => Kind);
251 -- The returned result
253 Last : String_List_Id := Nil_String;
254 -- Reference to the last string elements in Result, when Kind is List.
256 begin
257 Result.Project := Project;
258 Result.Location := Location_Of (First_Term);
260 -- Process each term of the expression, starting with First_Term
262 while The_Term /= Empty_Node loop
263 The_Current_Term := Current_Term (The_Term);
265 case Kind_Of (The_Current_Term) is
267 when N_Literal_String =>
269 case Kind is
271 when Undefined =>
273 -- Should never happen
275 pragma Assert (False, "Undefined expression kind");
276 raise Program_Error;
278 when Single =>
279 Add (Result.Value, String_Value_Of (The_Current_Term));
280 Result.Index := Source_Index_Of (The_Current_Term);
282 when List =>
284 String_Elements.Increment_Last;
286 if Last = Nil_String then
288 -- This can happen in an expression such as
289 -- () & "toto"
291 Result.Values := String_Elements.Last;
293 else
294 String_Elements.Table (Last).Next :=
295 String_Elements.Last;
296 end if;
298 Last := String_Elements.Last;
299 String_Elements.Table (Last) :=
300 (Value => String_Value_Of (The_Current_Term),
301 Index => Source_Index_Of (The_Current_Term),
302 Display_Value => No_Name,
303 Location => Location_Of (The_Current_Term),
304 Flag => False,
305 Next => Nil_String);
307 end case;
309 when N_Literal_String_List =>
311 declare
312 String_Node : Project_Node_Id :=
313 First_Expression_In_List (The_Current_Term);
315 Value : Variable_Value;
317 begin
318 if String_Node /= Empty_Node then
320 -- If String_Node is nil, it is an empty list,
321 -- there is nothing to do
323 Value := Expression
324 (Project => Project,
325 From_Project_Node => From_Project_Node,
326 Pkg => Pkg,
327 First_Term => Tree.First_Term (String_Node),
328 Kind => Single);
329 String_Elements.Increment_Last;
331 if Result.Values = Nil_String then
333 -- This literal string list is the first term
334 -- in a string list expression
336 Result.Values := String_Elements.Last;
338 else
339 String_Elements.Table (Last).Next :=
340 String_Elements.Last;
341 end if;
343 Last := String_Elements.Last;
344 String_Elements.Table (Last) :=
345 (Value => Value.Value,
346 Display_Value => No_Name,
347 Location => Value.Location,
348 Flag => False,
349 Next => Nil_String,
350 Index => Value.Index);
352 loop
353 -- Add the other element of the literal string list
354 -- one after the other
356 String_Node :=
357 Next_Expression_In_List (String_Node);
359 exit when String_Node = Empty_Node;
361 Value :=
362 Expression
363 (Project => Project,
364 From_Project_Node => From_Project_Node,
365 Pkg => Pkg,
366 First_Term => Tree.First_Term (String_Node),
367 Kind => Single);
369 String_Elements.Increment_Last;
370 String_Elements.Table (Last).Next :=
371 String_Elements.Last;
372 Last := String_Elements.Last;
373 String_Elements.Table (Last) :=
374 (Value => Value.Value,
375 Display_Value => No_Name,
376 Location => Value.Location,
377 Flag => False,
378 Next => Nil_String,
379 Index => Value.Index);
380 end loop;
382 end if;
384 end;
386 when N_Variable_Reference | N_Attribute_Reference =>
388 declare
389 The_Project : Project_Id := Project;
390 The_Package : Package_Id := Pkg;
391 The_Name : Name_Id := No_Name;
392 The_Variable_Id : Variable_Id := No_Variable;
393 The_Variable : Variable_Value;
394 Term_Project : constant Project_Node_Id :=
395 Project_Node_Of (The_Current_Term);
396 Term_Package : constant Project_Node_Id :=
397 Package_Node_Of (The_Current_Term);
398 Index : Name_Id := No_Name;
400 begin
401 if Term_Project /= Empty_Node and then
402 Term_Project /= From_Project_Node
403 then
404 -- This variable or attribute comes from another project
406 The_Name := Name_Of (Term_Project);
407 The_Project := Imported_Or_Extended_Project_From
408 (Project => Project,
409 With_Name => The_Name);
410 end if;
412 if Term_Package /= Empty_Node then
414 -- This is an attribute of a package
416 The_Name := Name_Of (Term_Package);
417 The_Package := Projects.Table (The_Project).Decl.Packages;
419 while The_Package /= No_Package
420 and then Packages.Table (The_Package).Name /= The_Name
421 loop
422 The_Package := Packages.Table (The_Package).Next;
423 end loop;
425 pragma Assert
426 (The_Package /= No_Package,
427 "package not found.");
429 elsif Kind_Of (The_Current_Term) = N_Attribute_Reference then
430 The_Package := No_Package;
431 end if;
433 The_Name := Name_Of (The_Current_Term);
435 if Kind_Of (The_Current_Term) = N_Attribute_Reference then
436 Index := Associative_Array_Index_Of (The_Current_Term);
437 end if;
439 -- If it is not an associative array attribute
441 if Index = No_Name then
443 -- It is not an associative array attribute
445 if The_Package /= No_Package then
447 -- First, if there is a package, look into the package
450 Kind_Of (The_Current_Term) = N_Variable_Reference
451 then
452 The_Variable_Id :=
453 Packages.Table (The_Package).Decl.Variables;
455 else
456 The_Variable_Id :=
457 Packages.Table (The_Package).Decl.Attributes;
458 end if;
460 while The_Variable_Id /= No_Variable
461 and then
462 Variable_Elements.Table (The_Variable_Id).Name /=
463 The_Name
464 loop
465 The_Variable_Id :=
466 Variable_Elements.Table (The_Variable_Id).Next;
467 end loop;
469 end if;
471 if The_Variable_Id = No_Variable then
473 -- If we have not found it, look into the project
476 Kind_Of (The_Current_Term) = N_Variable_Reference
477 then
478 The_Variable_Id :=
479 Projects.Table (The_Project).Decl.Variables;
481 else
482 The_Variable_Id :=
483 Projects.Table (The_Project).Decl.Attributes;
484 end if;
486 while The_Variable_Id /= No_Variable
487 and then
488 Variable_Elements.Table (The_Variable_Id).Name /=
489 The_Name
490 loop
491 The_Variable_Id :=
492 Variable_Elements.Table (The_Variable_Id).Next;
493 end loop;
495 end if;
497 pragma Assert (The_Variable_Id /= No_Variable,
498 "variable or attribute not found");
500 The_Variable := Variable_Elements.Table
501 (The_Variable_Id).Value;
503 else
505 -- It is an associative array attribute
507 declare
508 The_Array : Array_Id := No_Array;
509 The_Element : Array_Element_Id := No_Array_Element;
510 Array_Index : Name_Id := No_Name;
511 begin
512 if The_Package /= No_Package then
513 The_Array :=
514 Packages.Table (The_Package).Decl.Arrays;
516 else
517 The_Array :=
518 Projects.Table (The_Project).Decl.Arrays;
519 end if;
521 while The_Array /= No_Array
522 and then Arrays.Table (The_Array).Name /= The_Name
523 loop
524 The_Array := Arrays.Table (The_Array).Next;
525 end loop;
527 if The_Array /= No_Array then
528 The_Element := Arrays.Table (The_Array).Value;
530 Get_Name_String (Index);
532 if Case_Insensitive (The_Current_Term) then
533 To_Lower (Name_Buffer (1 .. Name_Len));
534 end if;
536 Array_Index := Name_Find;
538 while The_Element /= No_Array_Element
539 and then Array_Elements.Table (The_Element).Index
540 /= Array_Index
541 loop
542 The_Element :=
543 Array_Elements.Table (The_Element).Next;
544 end loop;
546 end if;
548 if The_Element /= No_Array_Element then
549 The_Variable :=
550 Array_Elements.Table (The_Element).Value;
552 else
554 Expression_Kind_Of (The_Current_Term) = List
555 then
556 The_Variable :=
557 (Project => Project,
558 Kind => List,
559 Location => No_Location,
560 Default => True,
561 Values => Nil_String);
563 else
564 The_Variable :=
565 (Project => Project,
566 Kind => Single,
567 Location => No_Location,
568 Default => True,
569 Value => Empty_String,
570 Index => 0);
571 end if;
572 end if;
573 end;
574 end if;
576 case Kind is
578 when Undefined =>
580 -- Should never happen
582 pragma Assert (False, "undefined expression kind");
583 null;
585 when Single =>
587 case The_Variable.Kind is
589 when Undefined =>
590 null;
592 when Single =>
593 Add (Result.Value, The_Variable.Value);
595 when List =>
597 -- Should never happen
599 pragma Assert
600 (False,
601 "list cannot appear in single " &
602 "string expression");
603 null;
604 end case;
606 when List =>
607 case The_Variable.Kind is
609 when Undefined =>
610 null;
612 when Single =>
613 String_Elements.Increment_Last;
615 if Last = Nil_String then
617 -- This can happen in an expression such as
618 -- () & Var
620 Result.Values := String_Elements.Last;
622 else
623 String_Elements.Table (Last).Next :=
624 String_Elements.Last;
625 end if;
627 Last := String_Elements.Last;
628 String_Elements.Table (Last) :=
629 (Value => The_Variable.Value,
630 Display_Value => No_Name,
631 Location => Location_Of (The_Current_Term),
632 Flag => False,
633 Next => Nil_String,
634 Index => 0);
636 when List =>
638 declare
639 The_List : String_List_Id :=
640 The_Variable.Values;
642 begin
643 while The_List /= Nil_String loop
644 String_Elements.Increment_Last;
646 if Last = Nil_String then
647 Result.Values := String_Elements.Last;
649 else
650 String_Elements.Table (Last).Next :=
651 String_Elements.Last;
653 end if;
655 Last := String_Elements.Last;
656 String_Elements.Table (Last) :=
657 (Value =>
658 String_Elements.Table
659 (The_List).Value,
660 Display_Value => No_Name,
661 Location => Location_Of
662 (The_Current_Term),
663 Flag => False,
664 Next => Nil_String,
665 Index => 0);
666 The_List :=
667 String_Elements.Table (The_List).Next;
668 end loop;
669 end;
670 end case;
671 end case;
672 end;
674 when N_External_Value =>
675 Get_Name_String
676 (String_Value_Of (External_Reference_Of (The_Current_Term)));
678 declare
679 Name : constant Name_Id := Name_Find;
680 Default : Name_Id := No_Name;
681 Value : Name_Id := No_Name;
683 Default_Node : constant Project_Node_Id :=
684 External_Default_Of (The_Current_Term);
686 begin
687 if Default_Node /= Empty_Node then
688 Default := String_Value_Of (Default_Node);
689 end if;
691 Value := Prj.Ext.Value_Of (Name, Default);
693 if Value = No_Name then
694 if not Opt.Quiet_Output then
695 if Error_Report = null then
696 Error_Msg
697 ("?undefined external reference",
698 Location_Of (The_Current_Term));
700 else
701 Error_Report
702 ("warning: """ & Get_Name_String (Name) &
703 """ is an undefined external reference",
704 Project);
705 end if;
706 end if;
708 Value := Empty_String;
710 end if;
712 case Kind is
714 when Undefined =>
715 null;
717 when Single =>
718 Add (Result.Value, Value);
720 when List =>
721 String_Elements.Increment_Last;
723 if Last = Nil_String then
724 Result.Values := String_Elements.Last;
726 else
727 String_Elements.Table (Last).Next :=
728 String_Elements.Last;
729 end if;
731 Last := String_Elements.Last;
732 String_Elements.Table (Last) :=
733 (Value => Value,
734 Display_Value => No_Name,
735 Location => Location_Of (The_Current_Term),
736 Flag => False,
737 Next => Nil_String,
738 Index => 0);
740 end case;
741 end;
743 when others =>
745 -- Should never happen
747 pragma Assert
748 (False,
749 "illegal node kind in an expression");
750 raise Program_Error;
752 end case;
754 The_Term := Next_Term (The_Term);
755 end loop;
757 return Result;
758 end Expression;
760 ---------------------------------------
761 -- Imported_Or_Extended_Project_From --
762 ---------------------------------------
764 function Imported_Or_Extended_Project_From
765 (Project : Project_Id;
766 With_Name : Name_Id) return Project_Id
768 Data : constant Project_Data := Projects.Table (Project);
769 List : Project_List := Data.Imported_Projects;
771 begin
772 -- First check if it is the name of a extended project
774 if Data.Extends /= No_Project
775 and then Projects.Table (Data.Extends).Name = With_Name
776 then
777 return Data.Extends;
779 else
780 -- Then check the name of each imported project
782 while List /= Empty_Project_List
783 and then
784 Projects.Table
785 (Project_Lists.Table (List).Project).Name /= With_Name
787 loop
788 List := Project_Lists.Table (List).Next;
789 end loop;
791 pragma Assert
792 (List /= Empty_Project_List,
793 "project not found");
795 return Project_Lists.Table (List).Project;
796 end if;
797 end Imported_Or_Extended_Project_From;
799 ------------------
800 -- Package_From --
801 ------------------
803 function Package_From
804 (Project : Project_Id;
805 With_Name : Name_Id) return Package_Id
807 Data : constant Project_Data := Projects.Table (Project);
808 Result : Package_Id := Data.Decl.Packages;
810 begin
811 -- Check the name of each existing package of Project
813 while Result /= No_Package
814 and then
815 Packages.Table (Result).Name /= With_Name
816 loop
817 Result := Packages.Table (Result).Next;
818 end loop;
820 if Result = No_Package then
821 -- Should never happen
822 Write_Line ("package """ & Get_Name_String (With_Name) &
823 """ not found");
824 raise Program_Error;
826 else
827 return Result;
828 end if;
829 end Package_From;
831 -------------
832 -- Process --
833 -------------
835 procedure Process
836 (Project : out Project_Id;
837 Success : out Boolean;
838 From_Project_Node : Project_Node_Id;
839 Report_Error : Put_Line_Access;
840 Process_Languages : Languages_Processed := Ada_Language;
841 Follow_Links : Boolean := True)
843 Obj_Dir : Name_Id;
844 Extending : Project_Id;
845 Extending2 : Project_Id;
847 begin
848 Error_Report := Report_Error;
849 Success := True;
851 -- Make sure there is no projects in the data structure
853 Projects.Set_Last (No_Project);
854 Processed_Projects.Reset;
856 -- And process the main project and all of the projects it depends on,
857 -- recursively
859 Recursive_Process
860 (Project => Project,
861 From_Project_Node => From_Project_Node,
862 Extended_By => No_Project);
864 if Project /= No_Project then
865 Check (Project, Process_Languages, Follow_Links);
866 end if;
868 -- If main project is an extending all project, set the object
869 -- directory of all virtual extending projects to the object directory
870 -- of the main project.
872 if Project /= No_Project
873 and then Is_Extending_All (From_Project_Node)
874 then
875 declare
876 Object_Dir : constant Name_Id :=
877 Projects.Table (Project).Object_Directory;
878 begin
879 for Index in Projects.First .. Projects.Last loop
880 if Projects.Table (Index).Virtual then
881 Projects.Table (Index).Object_Directory := Object_Dir;
882 end if;
883 end loop;
884 end;
885 end if;
887 -- Check that no extending project shares its object directory with
888 -- the project(s) it extends.
890 if Project /= No_Project then
891 for Proj in 1 .. Projects.Last loop
892 Extending := Projects.Table (Proj).Extended_By;
894 if Extending /= No_Project then
895 Obj_Dir := Projects.Table (Proj).Object_Directory;
897 -- Check that a project being extended does not share its
898 -- object directory with any project that extends it, directly
899 -- or indirectly, including a virtual extending project.
901 -- Start with the project directly extending it
903 Extending2 := Extending;
905 while Extending2 /= No_Project loop
906 if Projects.Table (Extending2).Sources_Present
907 and then
908 Projects.Table (Extending2).Object_Directory = Obj_Dir
909 then
910 if Projects.Table (Extending2).Virtual then
911 Error_Msg_Name_1 := Projects.Table (Proj).Name;
913 if Error_Report = null then
914 Error_Msg
915 ("project % cannot be extended by a virtual " &
916 "project with the same object directory",
917 Projects.Table (Proj).Location);
919 else
920 Error_Report
921 ("project """ &
922 Get_Name_String (Error_Msg_Name_1) &
923 """ cannot be extended by a virtual " &
924 "project with the same object directory",
925 Project);
926 end if;
928 else
929 Error_Msg_Name_1 :=
930 Projects.Table (Extending2).Name;
931 Error_Msg_Name_2 := Projects.Table (Proj).Name;
933 if Error_Report = null then
934 Error_Msg
935 ("project % cannot extend project %",
936 Projects.Table (Extending2).Location);
937 Error_Msg
938 ("\they share the same object directory",
939 Projects.Table (Extending2).Location);
941 else
942 Error_Report
943 ("project """ &
944 Get_Name_String (Error_Msg_Name_1) &
945 """ cannot extend project """ &
946 Get_Name_String (Error_Msg_Name_2) & """",
947 Project);
948 Error_Report
949 ("they share the same object directory",
950 Project);
951 end if;
952 end if;
953 end if;
955 -- Continue with the next extending project, if any
957 Extending2 := Projects.Table (Extending2).Extended_By;
958 end loop;
959 end if;
960 end loop;
961 end if;
963 Success := Total_Errors_Detected <= 0;
964 end Process;
966 -------------------------------
967 -- Process_Declarative_Items --
968 -------------------------------
970 procedure Process_Declarative_Items
971 (Project : Project_Id;
972 From_Project_Node : Project_Node_Id;
973 Pkg : Package_Id;
974 Item : Project_Node_Id)
976 Current_Declarative_Item : Project_Node_Id := Item;
977 Current_Item : Project_Node_Id := Empty_Node;
979 begin
980 -- For each declarative item
982 while Current_Declarative_Item /= Empty_Node loop
984 -- Get its data
986 Current_Item := Current_Item_Node (Current_Declarative_Item);
988 -- And set Current_Declarative_Item to the next declarative item
989 -- ready for the next iteration.
991 Current_Declarative_Item := Next_Declarative_Item
992 (Current_Declarative_Item);
994 case Kind_Of (Current_Item) is
996 when N_Package_Declaration =>
997 -- Do not process a package declaration that should be ignored
999 if Expression_Kind_Of (Current_Item) /= Ignored then
1000 -- Create the new package
1002 Packages.Increment_Last;
1004 declare
1005 New_Pkg : constant Package_Id := Packages.Last;
1006 The_New_Package : Package_Element;
1008 Project_Of_Renamed_Package : constant Project_Node_Id :=
1009 Project_Of_Renamed_Package_Of
1010 (Current_Item);
1012 begin
1013 -- Set the name of the new package
1015 The_New_Package.Name := Name_Of (Current_Item);
1017 -- Insert the new package in the appropriate list
1019 if Pkg /= No_Package then
1020 The_New_Package.Next :=
1021 Packages.Table (Pkg).Decl.Packages;
1022 Packages.Table (Pkg).Decl.Packages := New_Pkg;
1023 else
1024 The_New_Package.Next :=
1025 Projects.Table (Project).Decl.Packages;
1026 Projects.Table (Project).Decl.Packages := New_Pkg;
1027 end if;
1029 Packages.Table (New_Pkg) := The_New_Package;
1031 if Project_Of_Renamed_Package /= Empty_Node then
1033 -- Renamed package
1035 declare
1036 Project_Name : constant Name_Id :=
1037 Name_Of
1038 (Project_Of_Renamed_Package);
1040 Renamed_Project : constant Project_Id :=
1041 Imported_Or_Extended_Project_From
1042 (Project, Project_Name);
1044 Renamed_Package : constant Package_Id :=
1045 Package_From
1046 (Renamed_Project,
1047 Name_Of (Current_Item));
1049 begin
1050 -- For a renamed package, set declarations to
1051 -- the declarations of the renamed package.
1053 Packages.Table (New_Pkg).Decl :=
1054 Packages.Table (Renamed_Package).Decl;
1055 end;
1057 -- Standard package declaration, not renaming
1059 else
1060 -- Set the default values of the attributes
1062 Add_Attributes
1063 (Project,
1064 Packages.Table (New_Pkg).Decl,
1065 Package_Attributes.Table
1066 (Package_Id_Of (Current_Item)).First_Attribute);
1068 -- And process declarative items of the new package
1070 Process_Declarative_Items
1071 (Project => Project,
1072 From_Project_Node => From_Project_Node,
1073 Pkg => New_Pkg,
1074 Item => First_Declarative_Item_Of
1075 (Current_Item));
1076 end if;
1077 end;
1078 end if;
1080 when N_String_Type_Declaration =>
1082 -- There is nothing to process
1084 null;
1086 when N_Attribute_Declaration |
1087 N_Typed_Variable_Declaration |
1088 N_Variable_Declaration =>
1090 if Expression_Of (Current_Item) = Empty_Node then
1092 -- It must be a full associative array attribute declaration
1094 declare
1095 Current_Item_Name : constant Name_Id :=
1096 Name_Of (Current_Item);
1097 -- The name of the attribute
1099 New_Array : Array_Id;
1100 -- The new associative array created
1102 Orig_Array : Array_Id;
1103 -- The associative array value
1105 Orig_Project_Name : Name_Id := No_Name;
1106 -- The name of the project where the associative array
1107 -- value is.
1109 Orig_Project : Project_Id := No_Project;
1110 -- The id of the project where the associative array
1111 -- value is.
1113 Orig_Package_Name : Name_Id := No_Name;
1114 -- The name of the package, if any, where the associative
1115 -- array value is.
1117 Orig_Package : Package_Id := No_Package;
1118 -- The id of the package, if any, where the associative
1119 -- array value is.
1121 New_Element : Array_Element_Id := No_Array_Element;
1122 -- Id of a new array element created
1124 Prev_Element : Array_Element_Id := No_Array_Element;
1125 -- Last new element id created
1127 Orig_Element : Array_Element_Id := No_Array_Element;
1128 -- Current array element in the original associative
1129 -- array.
1131 Next_Element : Array_Element_Id := No_Array_Element;
1132 -- Id of the array element that follows the new element.
1133 -- This is not always nil, because values for the
1134 -- associative array attribute may already have been
1135 -- declared, and the array elements declared are reused.
1137 begin
1138 -- First, find if the associative array attribute already
1139 -- has elements declared.
1141 if Pkg /= No_Package then
1142 New_Array := Packages.Table (Pkg).Decl.Arrays;
1144 else
1145 New_Array := Projects.Table (Project).Decl.Arrays;
1146 end if;
1148 while New_Array /= No_Array and then
1149 Arrays.Table (New_Array).Name /= Current_Item_Name
1150 loop
1151 New_Array := Arrays.Table (New_Array).Next;
1152 end loop;
1154 -- If the attribute has never been declared add new entry
1155 -- in the arrays of the project/package and link it.
1157 if New_Array = No_Array then
1158 Arrays.Increment_Last;
1159 New_Array := Arrays.Last;
1161 if Pkg /= No_Package then
1162 Arrays.Table (New_Array) :=
1163 (Name => Current_Item_Name,
1164 Value => No_Array_Element,
1165 Next => Packages.Table (Pkg).Decl.Arrays);
1166 Packages.Table (Pkg).Decl.Arrays := New_Array;
1168 else
1169 Arrays.Table (New_Array) :=
1170 (Name => Current_Item_Name,
1171 Value => No_Array_Element,
1172 Next => Projects.Table (Project).Decl.Arrays);
1173 Projects.Table (Project).Decl.Arrays := New_Array;
1174 end if;
1175 end if;
1177 -- Find the project where the value is declared
1179 Orig_Project_Name :=
1180 Name_Of (Associative_Project_Of (Current_Item));
1182 for Index in Projects.First .. Projects.Last loop
1183 if Projects.Table (Index).Name = Orig_Project_Name then
1184 Orig_Project := Index;
1185 exit;
1186 end if;
1187 end loop;
1189 pragma Assert (Orig_Project /= No_Project,
1190 "original project not found");
1192 if Associative_Package_Of (Current_Item) = Empty_Node then
1193 Orig_Array :=
1194 Projects.Table (Orig_Project).Decl.Arrays;
1196 else
1197 -- If in a package, find the package where the
1198 -- value is declared.
1200 Orig_Package_Name :=
1201 Name_Of (Associative_Package_Of (Current_Item));
1202 Orig_Package :=
1203 Projects.Table (Orig_Project).Decl.Packages;
1204 pragma Assert (Orig_Package /= No_Package,
1205 "original package not found");
1207 while Packages.Table (Orig_Package).Name /=
1208 Orig_Package_Name
1209 loop
1210 Orig_Package := Packages.Table (Orig_Package).Next;
1211 pragma Assert (Orig_Package /= No_Package,
1212 "original package not found");
1213 end loop;
1215 Orig_Array :=
1216 Packages.Table (Orig_Package).Decl.Arrays;
1217 end if;
1219 -- Now look for the array
1221 while Orig_Array /= No_Array and then
1222 Arrays.Table (Orig_Array).Name /= Current_Item_Name
1223 loop
1224 Orig_Array := Arrays.Table (Orig_Array).Next;
1225 end loop;
1227 if Orig_Array = No_Array then
1228 if Error_Report = null then
1229 Error_Msg
1230 ("associative array value cannot be found",
1231 Location_Of (Current_Item));
1233 else
1234 Error_Report
1235 ("associative array value cannot be found",
1236 Project);
1237 end if;
1239 else
1240 Orig_Element := Arrays.Table (Orig_Array).Value;
1242 -- Copy each array element
1244 while Orig_Element /= No_Array_Element loop
1245 -- If it is the first element ...
1247 if Prev_Element = No_Array_Element then
1248 -- And there is no array element declared yet,
1249 -- create a new first array element.
1251 if Arrays.Table (New_Array).Value =
1252 No_Array_Element
1253 then
1254 Array_Elements.Increment_Last;
1255 New_Element := Array_Elements.Last;
1256 Arrays.Table (New_Array).Value := New_Element;
1257 Next_Element := No_Array_Element;
1259 -- Otherwise, the new element is the first
1261 else
1262 New_Element := Arrays.Table (New_Array).Value;
1263 Next_Element :=
1264 Array_Elements.Table (New_Element).Next;
1265 end if;
1267 -- Otherwise, reuse an existing element, or create
1268 -- one if necessary.
1270 else
1271 Next_Element :=
1272 Array_Elements.Table (Prev_Element).Next;
1274 if Next_Element = No_Array_Element then
1275 Array_Elements.Increment_Last;
1276 New_Element := Array_Elements.Last;
1278 else
1279 New_Element := Next_Element;
1280 Next_Element :=
1281 Array_Elements.Table (New_Element).Next;
1282 end if;
1283 end if;
1285 -- Copy the value of the element
1287 Array_Elements.Table (New_Element) :=
1288 Array_Elements.Table (Orig_Element);
1289 Array_Elements.Table (New_Element).Value.Project :=
1290 Project;
1292 -- Adjust the Next link
1294 Array_Elements.Table (New_Element).Next :=
1295 Next_Element;
1297 -- Adjust the previous id for the next element
1299 Prev_Element := New_Element;
1301 -- Go to the next element in the original array
1302 Orig_Element :=
1303 Array_Elements.Table (Orig_Element).Next;
1304 end loop;
1306 -- Make sure that the array ends here, in case there
1307 -- previously a greater number of elements.
1309 Array_Elements.Table (New_Element).Next :=
1310 No_Array_Element;
1311 end if;
1312 end;
1314 -- Declarations other that full associative arrays
1316 else
1317 declare
1318 New_Value : constant Variable_Value :=
1319 Expression
1320 (Project => Project,
1321 From_Project_Node => From_Project_Node,
1322 Pkg => Pkg,
1323 First_Term =>
1324 Tree.First_Term (Expression_Of
1325 (Current_Item)),
1326 Kind =>
1327 Expression_Kind_Of (Current_Item));
1328 -- The expression value
1330 The_Variable : Variable_Id := No_Variable;
1332 Current_Item_Name : constant Name_Id :=
1333 Name_Of (Current_Item);
1335 begin
1336 -- Process a typed variable declaration
1339 Kind_Of (Current_Item) = N_Typed_Variable_Declaration
1340 then
1341 -- Report an error for an empty string
1343 if New_Value.Value = Empty_String then
1344 Error_Msg_Name_1 := Name_Of (Current_Item);
1346 if Error_Report = null then
1347 Error_Msg
1348 ("no value defined for %",
1349 Location_Of (Current_Item));
1351 else
1352 Error_Report
1353 ("no value defined for " &
1354 Get_Name_String (Error_Msg_Name_1),
1355 Project);
1356 end if;
1358 else
1359 declare
1360 Current_String : Project_Node_Id :=
1361 First_Literal_String
1362 (String_Type_Of
1363 (Current_Item));
1365 begin
1366 -- Loop through all the valid strings for
1367 -- the string type and compare to the string
1368 -- value.
1370 while Current_String /= Empty_Node
1371 and then String_Value_Of (Current_String) /=
1372 New_Value.Value
1373 loop
1374 Current_String :=
1375 Next_Literal_String (Current_String);
1376 end loop;
1378 -- Report an error if the string value is not
1379 -- one for the string type.
1381 if Current_String = Empty_Node then
1382 Error_Msg_Name_1 := New_Value.Value;
1383 Error_Msg_Name_2 := Name_Of (Current_Item);
1385 if Error_Report = null then
1386 Error_Msg
1387 ("value { is illegal for typed string %",
1388 Location_Of (Current_Item));
1390 else
1391 Error_Report
1392 ("value """ &
1393 Get_Name_String (Error_Msg_Name_1) &
1394 """ is illegal for typed string """ &
1395 Get_Name_String (Error_Msg_Name_2) &
1396 """",
1397 Project);
1398 end if;
1399 end if;
1400 end;
1401 end if;
1402 end if;
1404 if Kind_Of (Current_Item) /= N_Attribute_Declaration
1405 or else
1406 Associative_Array_Index_Of (Current_Item) = No_Name
1407 then
1408 -- Case of a variable declaration or of a not
1409 -- associative array attribute.
1411 -- First, find the list where to find the variable
1412 -- or attribute.
1415 Kind_Of (Current_Item) = N_Attribute_Declaration
1416 then
1417 if Pkg /= No_Package then
1418 The_Variable :=
1419 Packages.Table (Pkg).Decl.Attributes;
1421 else
1422 The_Variable :=
1423 Projects.Table (Project).Decl.Attributes;
1424 end if;
1426 else
1427 if Pkg /= No_Package then
1428 The_Variable :=
1429 Packages.Table (Pkg).Decl.Variables;
1431 else
1432 The_Variable :=
1433 Projects.Table (Project).Decl.Variables;
1434 end if;
1436 end if;
1438 -- Loop through the list, to find if it has already
1439 -- been declared.
1441 while
1442 The_Variable /= No_Variable
1443 and then
1444 Variable_Elements.Table (The_Variable).Name /=
1445 Current_Item_Name
1446 loop
1447 The_Variable :=
1448 Variable_Elements.Table (The_Variable).Next;
1449 end loop;
1451 -- If it has not been declared, create a new entry
1452 -- in the list.
1454 if The_Variable = No_Variable then
1455 -- All single string attribute should already have
1456 -- been declared with a default empty string value.
1458 pragma Assert
1459 (Kind_Of (Current_Item) /=
1460 N_Attribute_Declaration,
1461 "illegal attribute declaration");
1463 Variable_Elements.Increment_Last;
1464 The_Variable := Variable_Elements.Last;
1466 -- Put the new variable in the appropriate list
1468 if Pkg /= No_Package then
1469 Variable_Elements.Table (The_Variable) :=
1470 (Next =>
1471 Packages.Table (Pkg).Decl.Variables,
1472 Name => Current_Item_Name,
1473 Value => New_Value);
1474 Packages.Table (Pkg).Decl.Variables :=
1475 The_Variable;
1477 else
1478 Variable_Elements.Table (The_Variable) :=
1479 (Next =>
1480 Projects.Table (Project).Decl.Variables,
1481 Name => Current_Item_Name,
1482 Value => New_Value);
1483 Projects.Table (Project).Decl.Variables :=
1484 The_Variable;
1485 end if;
1487 -- If the variable/attribute has already been
1488 -- declared, just change the value.
1490 else
1491 Variable_Elements.Table (The_Variable).Value :=
1492 New_Value;
1494 end if;
1496 else
1497 -- Associative array attribute
1499 -- Get the string index
1501 Get_Name_String
1502 (Associative_Array_Index_Of (Current_Item));
1504 -- Put in lower case, if necessary
1506 if Case_Insensitive (Current_Item) then
1507 GNAT.Case_Util.To_Lower
1508 (Name_Buffer (1 .. Name_Len));
1509 end if;
1511 declare
1512 The_Array : Array_Id;
1514 The_Array_Element : Array_Element_Id :=
1515 No_Array_Element;
1517 Index_Name : constant Name_Id := Name_Find;
1518 -- The name id of the index
1520 begin
1521 -- Look for the array in the appropriate list
1523 if Pkg /= No_Package then
1524 The_Array := Packages.Table (Pkg).Decl.Arrays;
1526 else
1527 The_Array := Projects.Table
1528 (Project).Decl.Arrays;
1529 end if;
1531 while
1532 The_Array /= No_Array
1533 and then Arrays.Table (The_Array).Name /=
1534 Current_Item_Name
1535 loop
1536 The_Array := Arrays.Table (The_Array).Next;
1537 end loop;
1539 -- If the array cannot be found, create a new
1540 -- entry in the list. As The_Array_Element is
1541 -- initialized to No_Array_Element, a new element
1542 -- will be created automatically later.
1544 if The_Array = No_Array then
1545 Arrays.Increment_Last;
1546 The_Array := Arrays.Last;
1548 if Pkg /= No_Package then
1549 Arrays.Table (The_Array) :=
1550 (Name => Current_Item_Name,
1551 Value => No_Array_Element,
1552 Next => Packages.Table (Pkg).Decl.Arrays);
1553 Packages.Table (Pkg).Decl.Arrays := The_Array;
1555 else
1556 Arrays.Table (The_Array) :=
1557 (Name => Current_Item_Name,
1558 Value => No_Array_Element,
1559 Next =>
1560 Projects.Table (Project).Decl.Arrays);
1561 Projects.Table (Project).Decl.Arrays :=
1562 The_Array;
1563 end if;
1565 -- Otherwise, initialize The_Array_Element as the
1566 -- head of the element list.
1568 else
1569 The_Array_Element :=
1570 Arrays.Table (The_Array).Value;
1571 end if;
1573 -- Look in the list, if any, to find an element
1574 -- with the same index.
1576 while The_Array_Element /= No_Array_Element
1577 and then
1578 Array_Elements.Table (The_Array_Element).Index /=
1579 Index_Name
1580 loop
1581 The_Array_Element :=
1582 Array_Elements.Table (The_Array_Element).Next;
1583 end loop;
1585 -- If no such element were found, create a new
1586 -- one and insert it in the element list, with
1587 -- the propoer value.
1589 if The_Array_Element = No_Array_Element then
1590 Array_Elements.Increment_Last;
1591 The_Array_Element := Array_Elements.Last;
1593 Array_Elements.Table (The_Array_Element) :=
1594 (Index => Index_Name,
1595 Src_Index => Source_Index_Of (Current_Item),
1596 Index_Case_Sensitive =>
1597 not Case_Insensitive (Current_Item),
1598 Value => New_Value,
1599 Next => Arrays.Table (The_Array).Value);
1600 Arrays.Table (The_Array).Value :=
1601 The_Array_Element;
1603 -- An element with the same index already exists,
1604 -- just replace its value with the new one.
1606 else
1607 Array_Elements.Table (The_Array_Element).Value :=
1608 New_Value;
1609 end if;
1610 end;
1611 end if;
1612 end;
1613 end if;
1615 when N_Case_Construction =>
1616 declare
1617 The_Project : Project_Id := Project;
1618 -- The id of the project of the case variable
1620 The_Package : Package_Id := Pkg;
1621 -- The id of the package, if any, of the case variable
1623 The_Variable : Variable_Value := Nil_Variable_Value;
1624 -- The case variable
1626 Case_Value : Name_Id := No_Name;
1627 -- The case variable value
1629 Case_Item : Project_Node_Id := Empty_Node;
1630 Choice_String : Project_Node_Id := Empty_Node;
1631 Decl_Item : Project_Node_Id := Empty_Node;
1633 begin
1634 declare
1635 Variable_Node : constant Project_Node_Id :=
1636 Case_Variable_Reference_Of
1637 (Current_Item);
1639 Var_Id : Variable_Id := No_Variable;
1640 Name : Name_Id := No_Name;
1642 begin
1643 -- If a project were specified for the case variable,
1644 -- get its id.
1646 if Project_Node_Of (Variable_Node) /= Empty_Node then
1647 Name := Name_Of (Project_Node_Of (Variable_Node));
1648 The_Project :=
1649 Imported_Or_Extended_Project_From (Project, Name);
1650 end if;
1652 -- If a package were specified for the case variable,
1653 -- get its id.
1655 if Package_Node_Of (Variable_Node) /= Empty_Node then
1656 Name := Name_Of (Package_Node_Of (Variable_Node));
1657 The_Package := Package_From (The_Project, Name);
1658 end if;
1660 Name := Name_Of (Variable_Node);
1662 -- First, look for the case variable into the package,
1663 -- if any.
1665 if The_Package /= No_Package then
1666 Var_Id := Packages.Table (The_Package).Decl.Variables;
1667 Name := Name_Of (Variable_Node);
1668 while Var_Id /= No_Variable
1669 and then
1670 Variable_Elements.Table (Var_Id).Name /= Name
1671 loop
1672 Var_Id := Variable_Elements.Table (Var_Id).Next;
1673 end loop;
1674 end if;
1676 -- If not found in the package, or if there is no
1677 -- package, look at the project level.
1679 if Var_Id = No_Variable
1680 and then Package_Node_Of (Variable_Node) = Empty_Node
1681 then
1682 Var_Id := Projects.Table (The_Project).Decl.Variables;
1683 while Var_Id /= No_Variable
1684 and then
1685 Variable_Elements.Table (Var_Id).Name /= Name
1686 loop
1687 Var_Id := Variable_Elements.Table (Var_Id).Next;
1688 end loop;
1689 end if;
1691 if Var_Id = No_Variable then
1693 -- Should never happen, because this has already been
1694 -- checked during parsing.
1696 Write_Line ("variable """ &
1697 Get_Name_String (Name) &
1698 """ not found");
1699 raise Program_Error;
1700 end if;
1702 -- Get the case variable
1704 The_Variable := Variable_Elements.Table (Var_Id).Value;
1706 if The_Variable.Kind /= Single then
1708 -- Should never happen, because this has already been
1709 -- checked during parsing.
1711 Write_Line ("variable""" &
1712 Get_Name_String (Name) &
1713 """ is not a single string variable");
1714 raise Program_Error;
1715 end if;
1717 -- Get the case variable value
1718 Case_Value := The_Variable.Value;
1719 end;
1721 -- Now look into all the case items of the case construction
1723 Case_Item := First_Case_Item_Of (Current_Item);
1724 Case_Item_Loop :
1725 while Case_Item /= Empty_Node loop
1726 Choice_String := First_Choice_Of (Case_Item);
1728 -- When Choice_String is nil, it means that it is
1729 -- the "when others =>" alternative.
1731 if Choice_String = Empty_Node then
1732 Decl_Item := First_Declarative_Item_Of (Case_Item);
1733 exit Case_Item_Loop;
1734 end if;
1736 -- Look into all the alternative of this case item
1738 Choice_Loop :
1739 while Choice_String /= Empty_Node loop
1741 Case_Value = String_Value_Of (Choice_String)
1742 then
1743 Decl_Item :=
1744 First_Declarative_Item_Of (Case_Item);
1745 exit Case_Item_Loop;
1746 end if;
1748 Choice_String :=
1749 Next_Literal_String (Choice_String);
1750 end loop Choice_Loop;
1751 Case_Item := Next_Case_Item (Case_Item);
1752 end loop Case_Item_Loop;
1754 -- If there is an alternative, then we process it
1756 if Decl_Item /= Empty_Node then
1757 Process_Declarative_Items
1758 (Project => Project,
1759 From_Project_Node => From_Project_Node,
1760 Pkg => Pkg,
1761 Item => Decl_Item);
1762 end if;
1763 end;
1765 when others =>
1767 -- Should never happen
1769 Write_Line ("Illegal declarative item: " &
1770 Project_Node_Kind'Image (Kind_Of (Current_Item)));
1771 raise Program_Error;
1772 end case;
1773 end loop;
1774 end Process_Declarative_Items;
1776 ---------------------
1777 -- Recursive_Check --
1778 ---------------------
1780 procedure Recursive_Check
1781 (Project : Project_Id;
1782 Process_Languages : Languages_Processed;
1783 Follow_Links : Boolean)
1785 Data : Project_Data;
1786 Imported_Project_List : Project_List := Empty_Project_List;
1788 begin
1789 -- Do nothing if Project is No_Project, or Project has already
1790 -- been marked as checked.
1792 if Project /= No_Project
1793 and then not Projects.Table (Project).Checked
1794 then
1795 -- Mark project as checked, to avoid infinite recursion in
1796 -- ill-formed trees, where a project imports itself.
1798 Projects.Table (Project).Checked := True;
1800 Data := Projects.Table (Project);
1802 -- Call itself for a possible extended project.
1803 -- (if there is no extended project, then nothing happens).
1805 Recursive_Check (Data.Extends, Process_Languages, Follow_Links);
1807 -- Call itself for all imported projects
1809 Imported_Project_List := Data.Imported_Projects;
1810 while Imported_Project_List /= Empty_Project_List loop
1811 Recursive_Check
1812 (Project_Lists.Table (Imported_Project_List).Project,
1813 Process_Languages, Follow_Links);
1814 Imported_Project_List :=
1815 Project_Lists.Table (Imported_Project_List).Next;
1816 end loop;
1818 if Opt.Verbose_Mode then
1819 Write_Str ("Checking project file """);
1820 Write_Str (Get_Name_String (Data.Name));
1821 Write_Line ("""");
1822 end if;
1824 case Process_Languages is
1825 when Ada_Language =>
1826 Prj.Nmsc.Ada_Check (Project, Error_Report, Follow_Links);
1828 when Other_Languages =>
1829 Prj.Nmsc.Other_Languages_Check (Project, Error_Report);
1830 end case;
1831 end if;
1832 end Recursive_Check;
1834 -----------------------
1835 -- Recursive_Process --
1836 -----------------------
1838 procedure Recursive_Process
1839 (Project : out Project_Id;
1840 From_Project_Node : Project_Node_Id;
1841 Extended_By : Project_Id)
1843 With_Clause : Project_Node_Id;
1845 begin
1846 if From_Project_Node = Empty_Node then
1847 Project := No_Project;
1849 else
1850 declare
1851 Processed_Data : Project_Data := Empty_Project;
1852 Imported : Project_List := Empty_Project_List;
1853 Declaration_Node : Project_Node_Id := Empty_Node;
1854 Name : constant Name_Id := Name_Of (From_Project_Node);
1856 begin
1857 Project := Processed_Projects.Get (Name);
1859 if Project /= No_Project then
1860 return;
1861 end if;
1863 Projects.Increment_Last;
1864 Project := Projects.Last;
1865 Processed_Projects.Set (Name, Project);
1867 Processed_Data.Name := Name;
1869 Get_Name_String (Name);
1871 -- If name starts with the virtual prefix, flag the project as
1872 -- being a virtual extending project.
1874 if Name_Len > Virtual_Prefix'Length
1875 and then Name_Buffer (1 .. Virtual_Prefix'Length) =
1876 Virtual_Prefix
1877 then
1878 Processed_Data.Virtual := True;
1879 end if;
1881 Processed_Data.Display_Path_Name :=
1882 Path_Name_Of (From_Project_Node);
1883 Get_Name_String (Processed_Data.Display_Path_Name);
1884 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1885 Processed_Data.Path_Name := Name_Find;
1887 Processed_Data.Location := Location_Of (From_Project_Node);
1889 Processed_Data.Display_Directory :=
1890 Directory_Of (From_Project_Node);
1891 Get_Name_String (Processed_Data.Display_Directory);
1892 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1893 Processed_Data.Directory := Name_Find;
1895 Processed_Data.Extended_By := Extended_By;
1896 Processed_Data.Naming := Standard_Naming_Data;
1898 Add_Attributes (Project, Processed_Data.Decl, Attribute_First);
1899 With_Clause := First_With_Clause_Of (From_Project_Node);
1901 while With_Clause /= Empty_Node loop
1902 declare
1903 New_Project : Project_Id;
1904 New_Data : Project_Data;
1906 begin
1907 Recursive_Process
1908 (Project => New_Project,
1909 From_Project_Node => Project_Node_Of (With_Clause),
1910 Extended_By => No_Project);
1911 New_Data := Projects.Table (New_Project);
1913 -- If we were the first project to import it,
1914 -- set First_Referred_By to us.
1916 if New_Data.First_Referred_By = No_Project then
1917 New_Data.First_Referred_By := Project;
1918 Projects.Table (New_Project) := New_Data;
1919 end if;
1921 -- Add this project to our list of imported projects
1923 Project_Lists.Increment_Last;
1924 Project_Lists.Table (Project_Lists.Last) :=
1925 (Project => New_Project, Next => Empty_Project_List);
1927 -- Imported is the id of the last imported project.
1928 -- If it is nil, then this imported project is our first.
1930 if Imported = Empty_Project_List then
1931 Processed_Data.Imported_Projects := Project_Lists.Last;
1933 else
1934 Project_Lists.Table (Imported).Next := Project_Lists.Last;
1935 end if;
1937 Imported := Project_Lists.Last;
1939 With_Clause := Next_With_Clause_Of (With_Clause);
1940 end;
1941 end loop;
1943 Declaration_Node := Project_Declaration_Of (From_Project_Node);
1945 Recursive_Process
1946 (Project => Processed_Data.Extends,
1947 From_Project_Node => Extended_Project_Of (Declaration_Node),
1948 Extended_By => Project);
1950 Projects.Table (Project) := Processed_Data;
1952 Process_Declarative_Items
1953 (Project => Project,
1954 From_Project_Node => From_Project_Node,
1955 Pkg => No_Package,
1956 Item => First_Declarative_Item_Of
1957 (Declaration_Node));
1959 -- If it is an extending project, inherit all packages
1960 -- from the extended project that are not explicitely defined
1961 -- or renamed. Also inherit the languages, if attribute Languages
1962 -- is not explicitely defined.
1964 if Processed_Data.Extends /= No_Project then
1965 Processed_Data := Projects.Table (Project);
1967 declare
1968 Extended_Pkg : Package_Id :=
1969 Projects.Table
1970 (Processed_Data.Extends).Decl.Packages;
1971 Current_Pkg : Package_Id;
1972 Element : Package_Element;
1973 First : constant Package_Id :=
1974 Processed_Data.Decl.Packages;
1975 Attribute1 : Variable_Id;
1976 Attribute2 : Variable_Id;
1977 Attr_Value1 : Variable;
1978 Attr_Value2 : Variable;
1980 begin
1981 while Extended_Pkg /= No_Package loop
1982 Element := Packages.Table (Extended_Pkg);
1984 Current_Pkg := First;
1986 loop
1987 exit when Current_Pkg = No_Package
1988 or else Packages.Table (Current_Pkg).Name
1989 = Element.Name;
1990 Current_Pkg := Packages.Table (Current_Pkg).Next;
1991 end loop;
1993 if Current_Pkg = No_Package then
1994 Packages.Increment_Last;
1995 Current_Pkg := Packages.Last;
1996 Packages.Table (Current_Pkg) :=
1997 (Name => Element.Name,
1998 Decl => Element.Decl,
1999 Parent => No_Package,
2000 Next => Processed_Data.Decl.Packages);
2001 Processed_Data.Decl.Packages := Current_Pkg;
2002 end if;
2004 Extended_Pkg := Element.Next;
2005 end loop;
2007 -- Check if attribute Languages is declared in the
2008 -- extending project.
2010 Attribute1 := Processed_Data.Decl.Attributes;
2011 while Attribute1 /= No_Variable loop
2012 Attr_Value1 := Variable_Elements.Table (Attribute1);
2013 exit when Attr_Value1.Name = Snames.Name_Languages;
2014 Attribute1 := Attr_Value1.Next;
2015 end loop;
2017 if Attribute1 = No_Variable or else
2018 Attr_Value1.Value.Default
2019 then
2020 -- Attribute Languages is not declared in the extending
2021 -- project. Check if it is declared in the project being
2022 -- extended.
2024 Attribute2 :=
2025 Projects.Table (Processed_Data.Extends).Decl.Attributes;
2027 while Attribute2 /= No_Variable loop
2028 Attr_Value2 := Variable_Elements.Table (Attribute2);
2029 exit when Attr_Value2.Name = Snames.Name_Languages;
2030 Attribute2 := Attr_Value2.Next;
2031 end loop;
2033 if Attribute2 /= No_Variable and then
2034 not Attr_Value2.Value.Default
2035 then
2036 -- As attribute Languages is declared in the project
2037 -- being extended, copy its value for the extending
2038 -- project.
2040 if Attribute1 = No_Variable then
2041 Variable_Elements.Increment_Last;
2042 Attribute1 := Variable_Elements.Last;
2043 Attr_Value1.Next := Processed_Data.Decl.Attributes;
2044 Processed_Data.Decl.Attributes := Attribute1;
2045 end if;
2047 Attr_Value1.Name := Snames.Name_Languages;
2048 Attr_Value1.Value := Attr_Value2.Value;
2049 Variable_Elements.Table (Attribute1) := Attr_Value1;
2050 end if;
2051 end if;
2052 end;
2054 Projects.Table (Project) := Processed_Data;
2055 end if;
2056 end;
2057 end if;
2058 end Recursive_Process;
2060 end Prj.Proc;