1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2011, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Err_Vars; use Err_Vars;
28 with Osint; use Osint;
29 with Output; use Output;
30 with Prj.Attr; use Prj.Attr;
32 with Prj.Err; use Prj.Err;
33 with Prj.Ext; use Prj.Ext;
34 with Prj.Nmsc; use Prj.Nmsc;
38 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
40 with GNAT.Case_Util; use GNAT.Case_Util;
43 package body Prj.Proc is
45 package Processed_Projects is new GNAT.HTable.Simple_HTable
46 (Header_Num => Header_Num,
47 Element => Project_Id,
48 No_Element => No_Project,
52 -- This hash table contains all processed projects
54 package Unit_Htable is new GNAT.HTable.Simple_HTable
55 (Header_Num => Header_Num,
57 No_Element => No_Source,
61 -- This hash table contains all processed projects
63 procedure Add (To_Exp : in out Name_Id; Str : Name_Id);
64 -- Concatenate two strings and returns another string if both
65 -- arguments are not null string.
67 -- In the following procedures, we are expected to guess the meaning of
68 -- the parameters from their names, this is never a good idea, comments
69 -- should be added precisely defining every formal ???
71 procedure Add_Attributes
72 (Project : Project_Id;
73 Project_Name : Name_Id;
74 Project_Dir : Name_Id;
75 Shared : Shared_Project_Tree_Data_Access;
76 Decl : in out Declarations;
77 First : Attribute_Node_Id;
78 Project_Level : Boolean);
79 -- Add all attributes, starting with First, with their default values to
80 -- the package or project with declarations Decl.
83 (In_Tree : Project_Tree_Ref;
85 Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
86 Flags : Processing_Flags);
87 -- Set all projects to not checked, then call Recursive_Check for the
88 -- main project Project. Project is set to No_Project if errors occurred.
89 -- Current_Dir is for optimization purposes, avoiding extra system calls.
90 -- If Allow_Duplicate_Basenames, then files with the same base names are
91 -- authorized within a project for source-based languages (never for unit
94 procedure Copy_Package_Declarations
96 To : in out Declarations;
99 Shared : Shared_Project_Tree_Data_Access);
100 -- Copy a package declaration From to To for a renamed package. Change the
101 -- locations of all the attributes to New_Loc. When Restricted is
102 -- True, do not copy attributes Body, Spec, Implementation, Specification
103 -- and Linker_Options.
106 (Project : Project_Id;
107 Shared : Shared_Project_Tree_Data_Access;
108 From_Project_Node : Project_Node_Id;
109 From_Project_Node_Tree : Project_Node_Tree_Ref;
110 Env : Prj.Tree.Environment;
112 First_Term : Project_Node_Id;
113 Kind : Variable_Kind) return Variable_Value;
114 -- From N_Expression project node From_Project_Node, compute the value
115 -- of an expression and return it as a Variable_Value.
117 function Imported_Or_Extended_Project_From
118 (Project : Project_Id;
119 With_Name : Name_Id) return Project_Id;
120 -- Find an imported or extended project of Project whose name is With_Name
122 function Package_From
123 (Project : Project_Id;
124 Shared : Shared_Project_Tree_Data_Access;
125 With_Name : Name_Id) return Package_Id;
126 -- Find the package of Project whose name is With_Name
128 procedure Process_Declarative_Items
129 (Project : Project_Id;
130 In_Tree : Project_Tree_Ref;
131 From_Project_Node : Project_Node_Id;
132 Node_Tree : Project_Node_Tree_Ref;
133 Env : Prj.Tree.Environment;
135 Item : Project_Node_Id;
136 Child_Env : in out Prj.Tree.Environment);
137 -- Process declarative items starting with From_Project_Node, and put them
138 -- in declarations Decl. This is a recursive procedure; it calls itself for
139 -- a package declaration or a case construction.
141 -- Child_Env is the modified environment after seeing declarations like
142 -- "for External(...) use" or "for Project_Path use" in aggregate projects.
143 -- It should have been initialized first.
145 procedure Recursive_Process
146 (In_Tree : Project_Tree_Ref;
147 Project : out Project_Id;
148 Packages_To_Check : String_List_Access;
149 From_Project_Node : Project_Node_Id;
150 From_Project_Node_Tree : Project_Node_Tree_Ref;
151 Env : in out Prj.Tree.Environment;
152 Extended_By : Project_Id);
153 -- Process project with node From_Project_Node in the tree. Do nothing if
154 -- From_Project_Node is Empty_Node. If project has already been processed,
155 -- simply return its project id. Otherwise create a new project id, mark it
156 -- as processed, call itself recursively for all imported projects and a
157 -- extended project, if any. Then process the declarative items of the
160 -- Is_Root_Project should be true only for the project that the user
161 -- explicitly loaded. In the context of aggregate projects, only that
162 -- project is allowed to modify the environment that will be used to load
163 -- projects (Child_Env).
165 function Get_Attribute_Index
166 (Tree : Project_Node_Tree_Ref;
167 Attr : Project_Node_Id;
168 Index : Name_Id) return Name_Id;
169 -- Copy the index of the attribute into Name_Buffer, converting to lower
170 -- case if the attribute is case-insensitive.
176 procedure Add (To_Exp : in out Name_Id; Str : Name_Id) is
178 if To_Exp = No_Name or else To_Exp = Empty_String then
180 -- To_Exp is nil or empty. The result is Str
184 -- If Str is nil, then do not change To_Ext
186 elsif Str /= No_Name and then Str /= Empty_String then
188 S : constant String := Get_Name_String (Str);
190 Get_Name_String (To_Exp);
191 Add_Str_To_Name_Buffer (S);
201 procedure Add_Attributes
202 (Project : Project_Id;
203 Project_Name : Name_Id;
204 Project_Dir : Name_Id;
205 Shared : Shared_Project_Tree_Data_Access;
206 Decl : in out Declarations;
207 First : Attribute_Node_Id;
208 Project_Level : Boolean)
210 The_Attribute : Attribute_Node_Id := First;
213 while The_Attribute /= Empty_Attribute loop
214 if Attribute_Kind_Of (The_Attribute) = Single then
216 New_Attribute : Variable_Value;
219 case Variable_Kind_Of (The_Attribute) is
221 -- Undefined should not happen
225 (False, "attribute with an undefined kind");
228 -- Single attributes have a default value of empty string
234 Location => No_Location,
236 Value => Empty_String,
239 -- Special cases of <project>'Name and
240 -- <project>'Project_Dir.
242 if Project_Level then
243 if Attribute_Name_Of (The_Attribute) =
246 New_Attribute.Value := Project_Name;
248 elsif Attribute_Name_Of (The_Attribute) =
249 Snames.Name_Project_Dir
251 New_Attribute.Value := Project_Dir;
255 -- List attributes have a default value of nil list
261 Location => No_Location,
263 Values => Nil_String);
267 Variable_Element_Table.Increment_Last
268 (Shared.Variable_Elements);
269 Shared.Variable_Elements.Table
270 (Variable_Element_Table.Last (Shared.Variable_Elements)) :=
271 (Next => Decl.Attributes,
272 Name => Attribute_Name_Of (The_Attribute),
273 Value => New_Attribute);
275 Variable_Element_Table.Last
276 (Shared.Variable_Elements);
280 The_Attribute := Next_Attribute (After => The_Attribute);
289 (In_Tree : Project_Tree_Ref;
290 Project : Project_Id;
291 Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
292 Flags : Processing_Flags)
295 Process_Naming_Scheme (In_Tree, Project, Node_Tree, Flags);
297 -- Set the Other_Part field for the units
303 Iter : Source_Iterator;
308 Iter := For_Each_Source (In_Tree);
310 Source1 := Prj.Element (Iter);
311 exit when Source1 = No_Source;
313 if Source1.Unit /= No_Unit_Index then
314 Name := Source1.Unit.Name;
315 Source2 := Unit_Htable.Get (Name);
317 if Source2 = No_Source then
318 Unit_Htable.Set (K => Name, E => Source1);
320 Unit_Htable.Remove (Name);
329 -------------------------------
330 -- Copy_Package_Declarations --
331 -------------------------------
333 procedure Copy_Package_Declarations
334 (From : Declarations;
335 To : in out Declarations;
336 New_Loc : Source_Ptr;
337 Restricted : Boolean;
338 Shared : Shared_Project_Tree_Data_Access)
341 V2 : Variable_Id := No_Variable;
344 A2 : Array_Id := No_Array;
346 E1 : Array_Element_Id;
347 E2 : Array_Element_Id := No_Array_Element;
351 -- To avoid references in error messages to attribute declarations in
352 -- an original package that has been renamed, copy all the attribute
353 -- declarations of the package and change all locations to New_Loc,
354 -- the location of the renamed package.
356 -- First single attributes
358 V1 := From.Attributes;
359 while V1 /= No_Variable loop
361 -- Copy the attribute
363 Var := Shared.Variable_Elements.Table (V1);
366 -- Do not copy the value of attribute Linker_Options if Restricted
368 if Restricted and then Var.Name = Snames.Name_Linker_Options then
369 Var.Value.Values := Nil_String;
372 -- Remove the Next component
374 Var.Next := No_Variable;
376 -- Change the location to New_Loc
378 Var.Value.Location := New_Loc;
379 Variable_Element_Table.Increment_Last (Shared.Variable_Elements);
381 -- Put in new declaration
383 if To.Attributes = No_Variable then
385 Variable_Element_Table.Last (Shared.Variable_Elements);
387 Shared.Variable_Elements.Table (V2).Next :=
388 Variable_Element_Table.Last (Shared.Variable_Elements);
391 V2 := Variable_Element_Table.Last (Shared.Variable_Elements);
392 Shared.Variable_Elements.Table (V2) := Var;
395 -- Then the associated array attributes
398 while A1 /= No_Array loop
399 Arr := Shared.Arrays.Table (A1);
402 -- Remove the Next component
404 Arr.Next := No_Array;
405 Array_Table.Increment_Last (Shared.Arrays);
407 -- Create new Array declaration
409 if To.Arrays = No_Array then
410 To.Arrays := Array_Table.Last (Shared.Arrays);
412 Shared.Arrays.Table (A2).Next :=
413 Array_Table.Last (Shared.Arrays);
416 A2 := Array_Table.Last (Shared.Arrays);
418 -- Don't store the array as its first element has not been set yet
420 -- Copy the array elements of the array
423 Arr.Value := No_Array_Element;
424 while E1 /= No_Array_Element loop
426 -- Copy the array element
428 Elm := Shared.Array_Elements.Table (E1);
431 -- Remove the Next component
433 Elm.Next := No_Array_Element;
435 Elm.Restricted := Restricted;
437 -- Change the location
439 Elm.Value.Location := New_Loc;
440 Array_Element_Table.Increment_Last (Shared.Array_Elements);
442 -- Create new array element
444 if Arr.Value = No_Array_Element then
445 Arr.Value := Array_Element_Table.Last (Shared.Array_Elements);
447 Shared.Array_Elements.Table (E2).Next :=
448 Array_Element_Table.Last (Shared.Array_Elements);
451 E2 := Array_Element_Table.Last (Shared.Array_Elements);
452 Shared.Array_Elements.Table (E2) := Elm;
455 -- Finally, store the new array
457 Shared.Arrays.Table (A2) := Arr;
459 end Copy_Package_Declarations;
461 -------------------------
462 -- Get_Attribute_Index --
463 -------------------------
465 function Get_Attribute_Index
466 (Tree : Project_Node_Tree_Ref;
467 Attr : Project_Node_Id;
468 Index : Name_Id) return Name_Id
471 if Index = All_Other_Names
472 or else not Case_Insensitive (Attr, Tree)
477 Get_Name_String (Index);
478 To_Lower (Name_Buffer (1 .. Name_Len));
480 end Get_Attribute_Index;
487 (Project : Project_Id;
488 Shared : Shared_Project_Tree_Data_Access;
489 From_Project_Node : Project_Node_Id;
490 From_Project_Node_Tree : Project_Node_Tree_Ref;
491 Env : Prj.Tree.Environment;
493 First_Term : Project_Node_Id;
494 Kind : Variable_Kind) return Variable_Value
496 The_Term : Project_Node_Id;
497 -- The term in the expression list
499 The_Current_Term : Project_Node_Id := Empty_Node;
500 -- The current term node id
502 Result : Variable_Value (Kind => Kind);
503 -- The returned result
505 Last : String_List_Id := Nil_String;
506 -- Reference to the last string elements in Result, when Kind is List
509 Result.Project := Project;
510 Result.Location := Location_Of (First_Term, From_Project_Node_Tree);
512 -- Process each term of the expression, starting with First_Term
514 The_Term := First_Term;
515 while Present (The_Term) loop
516 The_Current_Term := Current_Term (The_Term, From_Project_Node_Tree);
518 case Kind_Of (The_Current_Term, From_Project_Node_Tree) is
520 when N_Literal_String =>
526 -- Should never happen
528 pragma Assert (False, "Undefined expression kind");
534 (The_Current_Term, From_Project_Node_Tree));
537 (The_Current_Term, From_Project_Node_Tree);
541 String_Element_Table.Increment_Last
542 (Shared.String_Elements);
544 if Last = Nil_String then
546 -- This can happen in an expression like () & "toto"
548 Result.Values := String_Element_Table.Last
549 (Shared.String_Elements);
552 Shared.String_Elements.Table
553 (Last).Next := String_Element_Table.Last
554 (Shared.String_Elements);
557 Last := String_Element_Table.Last
558 (Shared.String_Elements);
560 Shared.String_Elements.Table (Last) :=
561 (Value => String_Value_Of
563 From_Project_Node_Tree),
564 Index => Source_Index_Of
566 From_Project_Node_Tree),
567 Display_Value => No_Name,
568 Location => Location_Of
570 From_Project_Node_Tree),
575 when N_Literal_String_List =>
578 String_Node : Project_Node_Id :=
579 First_Expression_In_List
581 From_Project_Node_Tree);
583 Value : Variable_Value;
586 if Present (String_Node) then
588 -- If String_Node is nil, it is an empty list, there is
594 From_Project_Node => From_Project_Node,
595 From_Project_Node_Tree => From_Project_Node_Tree,
600 (String_Node, From_Project_Node_Tree),
602 String_Element_Table.Increment_Last
603 (Shared.String_Elements);
605 if Result.Values = Nil_String then
607 -- This literal string list is the first term in a
608 -- string list expression
611 String_Element_Table.Last
612 (Shared.String_Elements);
615 Shared.String_Elements.Table (Last).Next :=
616 String_Element_Table.Last (Shared.String_Elements);
620 String_Element_Table.Last (Shared.String_Elements);
622 Shared.String_Elements.Table (Last) :=
623 (Value => Value.Value,
624 Display_Value => No_Name,
625 Location => Value.Location,
628 Index => Value.Index);
631 -- Add the other element of the literal string list
632 -- one after the other.
635 Next_Expression_In_List
636 (String_Node, From_Project_Node_Tree);
638 exit when No (String_Node);
644 From_Project_Node => From_Project_Node,
645 From_Project_Node_Tree => From_Project_Node_Tree,
650 (String_Node, From_Project_Node_Tree),
653 String_Element_Table.Increment_Last
654 (Shared.String_Elements);
655 Shared.String_Elements.Table (Last).Next :=
656 String_Element_Table.Last (Shared.String_Elements);
657 Last := String_Element_Table.Last
658 (Shared.String_Elements);
659 Shared.String_Elements.Table (Last) :=
660 (Value => Value.Value,
661 Display_Value => No_Name,
662 Location => Value.Location,
665 Index => Value.Index);
670 when N_Variable_Reference | N_Attribute_Reference =>
673 The_Project : Project_Id := Project;
674 The_Package : Package_Id := Pkg;
675 The_Name : Name_Id := No_Name;
676 The_Variable_Id : Variable_Id := No_Variable;
677 The_Variable : Variable_Value;
678 Term_Project : constant Project_Node_Id :=
681 From_Project_Node_Tree);
682 Term_Package : constant Project_Node_Id :=
685 From_Project_Node_Tree);
686 Index : Name_Id := No_Name;
689 if Present (Term_Project)
690 and then Term_Project /= From_Project_Node
692 -- This variable or attribute comes from another project
695 Name_Of (Term_Project, From_Project_Node_Tree);
696 The_Project := Imported_Or_Extended_Project_From
698 With_Name => The_Name);
701 if Present (Term_Package) then
703 -- This is an attribute of a package
706 Name_Of (Term_Package, From_Project_Node_Tree);
708 The_Package := The_Project.Decl.Packages;
709 while The_Package /= No_Package
710 and then Shared.Packages.Table (The_Package).Name /=
714 Shared.Packages.Table (The_Package).Next;
718 (The_Package /= No_Package, "package not found.");
720 elsif Kind_Of (The_Current_Term, From_Project_Node_Tree) =
721 N_Attribute_Reference
723 The_Package := No_Package;
727 Name_Of (The_Current_Term, From_Project_Node_Tree);
729 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
730 N_Attribute_Reference
733 Associative_Array_Index_Of
734 (The_Current_Term, From_Project_Node_Tree);
737 -- If it is not an associative array attribute
739 if Index = No_Name then
741 -- It is not an associative array attribute
743 if The_Package /= No_Package then
745 -- First, if there is a package, look into the package
747 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
751 Shared.Packages.Table
752 (The_Package).Decl.Variables;
755 Shared.Packages.Table
756 (The_Package).Decl.Attributes;
759 while The_Variable_Id /= No_Variable
760 and then Shared.Variable_Elements.Table
761 (The_Variable_Id).Name /= The_Name
764 Shared.Variable_Elements.Table
765 (The_Variable_Id).Next;
770 if The_Variable_Id = No_Variable then
772 -- If we have not found it, look into the project
774 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
777 The_Variable_Id := The_Project.Decl.Variables;
779 The_Variable_Id := The_Project.Decl.Attributes;
782 while The_Variable_Id /= No_Variable
783 and then Shared.Variable_Elements.Table
784 (The_Variable_Id).Name /= The_Name
787 Shared.Variable_Elements.Table
788 (The_Variable_Id).Next;
793 pragma Assert (The_Variable_Id /= No_Variable,
794 "variable or attribute not found");
797 Shared.Variable_Elements.Table (The_Variable_Id).Value;
801 -- It is an associative array attribute
804 The_Array : Array_Id := No_Array;
805 The_Element : Array_Element_Id := No_Array_Element;
806 Array_Index : Name_Id := No_Name;
809 if The_Package /= No_Package then
811 Shared.Packages.Table (The_Package).Decl.Arrays;
813 The_Array := The_Project.Decl.Arrays;
816 while The_Array /= No_Array
817 and then Shared.Arrays.Table (The_Array).Name /=
820 The_Array := Shared.Arrays.Table (The_Array).Next;
823 if The_Array /= No_Array then
825 Shared.Arrays.Table (The_Array).Value;
828 (From_Project_Node_Tree,
832 while The_Element /= No_Array_Element
833 and then Shared.Array_Elements.Table
834 (The_Element).Index /= Array_Index
837 Shared.Array_Elements.Table (The_Element).Next;
842 if The_Element /= No_Array_Element then
844 Shared.Array_Elements.Table (The_Element).Value;
847 if Expression_Kind_Of
848 (The_Current_Term, From_Project_Node_Tree) =
854 Location => No_Location,
856 Values => Nil_String);
861 Location => No_Location,
863 Value => Empty_String,
874 -- Should never happen
876 pragma Assert (False, "undefined expression kind");
881 case The_Variable.Kind is
887 Add (Result.Value, The_Variable.Value);
891 -- Should never happen
895 "list cannot appear in single " &
896 "string expression");
901 case The_Variable.Kind is
907 String_Element_Table.Increment_Last
908 (Shared.String_Elements);
910 if Last = Nil_String then
912 -- This can happen in an expression such as
916 String_Element_Table.Last
917 (Shared.String_Elements);
920 Shared.String_Elements.Table (Last).Next :=
921 String_Element_Table.Last
922 (Shared.String_Elements);
926 String_Element_Table.Last
927 (Shared.String_Elements);
929 Shared.String_Elements.Table (Last) :=
930 (Value => The_Variable.Value,
931 Display_Value => No_Name,
932 Location => Location_Of
934 From_Project_Node_Tree),
942 The_List : String_List_Id :=
946 while The_List /= Nil_String loop
947 String_Element_Table.Increment_Last
948 (Shared.String_Elements);
950 if Last = Nil_String then
952 String_Element_Table.Last
953 (Shared.String_Elements);
957 String_Elements.Table (Last).Next :=
958 String_Element_Table.Last
959 (Shared.String_Elements);
964 String_Element_Table.Last
965 (Shared.String_Elements);
967 Shared.String_Elements.Table
970 Shared.String_Elements.Table
972 Display_Value => No_Name,
976 From_Project_Node_Tree),
981 The_List := Shared.String_Elements.Table
989 when N_External_Value =>
992 (External_Reference_Of
993 (The_Current_Term, From_Project_Node_Tree),
994 From_Project_Node_Tree));
997 Name : constant Name_Id := Name_Find;
998 Default : Name_Id := No_Name;
999 Value : Name_Id := No_Name;
1000 Ext_List : Boolean := False;
1001 Str_List : String_List_Access := null;
1002 Def_Var : Variable_Value;
1004 Default_Node : constant Project_Node_Id :=
1007 From_Project_Node_Tree);
1010 -- If there is a default value for the external reference,
1013 if Present (Default_Node) then
1014 Def_Var := Expression
1015 (Project => Project,
1017 From_Project_Node => From_Project_Node,
1018 From_Project_Node_Tree => From_Project_Node_Tree,
1023 (Default_Node, From_Project_Node_Tree),
1026 if Def_Var /= Nil_Variable_Value then
1027 Default := Def_Var.Value;
1031 Ext_List := Expression_Kind_Of
1033 From_Project_Node_Tree) = List;
1036 Value := Prj.Ext.Value_Of (Env.External, Name, No_Name);
1038 if Value /= No_Name then
1040 Sep : constant String :=
1041 Get_Name_String (Default);
1042 First : Positive := 1;
1044 Done : Boolean := False;
1048 Get_Name_String (Value);
1051 or else Sep'Length = 0
1052 or else Name_Buffer (1 .. Name_Len) = Sep
1057 if not Done and then Name_Len < Sep'Length then
1061 (Name_Buffer (1 .. Name_Len)));
1066 if Name_Buffer (1 .. Sep'Length) = Sep then
1067 First := Sep'Length + 1;
1070 if Name_Len - First + 1 >= Sep'Length
1072 Name_Buffer (Name_Len - Sep'Length + 1 ..
1075 Name_Len := Name_Len - Sep'Length;
1078 if Name_Len = 0 then
1080 new String_List'(1 => new String'(""));
1087 -- Count the number of strings
1090 Saved : constant Positive := First;
1098 Name_Buffer (First .. Name_Len),
1102 First := Lst + Sep'Length;
1108 Str_List := new String_List (1 .. Nmb);
1110 -- Populate the string list
1117 Name_Buffer (First .. Name_Len),
1123 (Name_Buffer (First .. Name_Len));
1129 (Name_Buffer (First .. Lst - 1));
1131 First := Lst + Sep'Length;
1141 Value := Prj.Ext.Value_Of (Env.External, Name, Default);
1143 if Value = No_Name then
1144 if not Quiet_Output then
1146 (Env.Flags, "?undefined external reference",
1148 (The_Current_Term, From_Project_Node_Tree),
1152 Value := Empty_String;
1166 Add (Result.Value, Value);
1170 if not Ext_List or else Str_List /= null then
1171 String_Element_Table.Increment_Last
1172 (Shared.String_Elements);
1174 if Last = Nil_String then
1176 String_Element_Table.Last
1177 (Shared.String_Elements);
1180 Shared.String_Elements.Table (Last).Next
1181 := String_Element_Table.Last
1182 (Shared.String_Elements);
1185 Last := String_Element_Table.Last
1186 (Shared.String_Elements);
1189 for Ind in Str_List'Range loop
1191 Add_Str_To_Name_Buffer (Str_List (Ind).all);
1193 Shared.String_Elements.Table (Last) :=
1195 Display_Value => No_Name,
1199 From_Project_Node_Tree),
1204 if Ind /= Str_List'Last then
1205 String_Element_Table.Increment_Last
1206 (Shared.String_Elements);
1207 Shared.String_Elements.Table (Last).Next :=
1208 String_Element_Table.Last
1209 (Shared.String_Elements);
1210 Last := String_Element_Table.Last
1211 (Shared.String_Elements);
1216 Shared.String_Elements.Table (Last) :=
1218 Display_Value => No_Name,
1222 From_Project_Node_Tree),
1233 -- Should never happen
1237 "illegal node kind in an expression");
1238 raise Program_Error;
1242 The_Term := Next_Term (The_Term, From_Project_Node_Tree);
1248 ---------------------------------------
1249 -- Imported_Or_Extended_Project_From --
1250 ---------------------------------------
1252 function Imported_Or_Extended_Project_From
1253 (Project : Project_Id;
1254 With_Name : Name_Id) return Project_Id
1256 List : Project_List;
1257 Result : Project_Id;
1258 Temp_Result : Project_Id;
1261 -- First check if it is the name of an extended project
1263 Result := Project.Extends;
1264 while Result /= No_Project loop
1265 if Result.Name = With_Name then
1268 Result := Result.Extends;
1272 -- Then check the name of each imported project
1274 Temp_Result := No_Project;
1275 List := Project.Imported_Projects;
1276 while List /= null loop
1277 Result := List.Project;
1279 -- If the project is directly imported, then returns its ID
1281 if Result.Name = With_Name then
1285 -- If a project extending the project is imported, then keep this
1286 -- extending project as a possibility. It will be the returned ID
1287 -- if the project is not imported directly.
1293 Proj := Result.Extends;
1294 while Proj /= No_Project loop
1295 if Proj.Name = With_Name then
1296 Temp_Result := Result;
1300 Proj := Proj.Extends;
1307 pragma Assert (Temp_Result /= No_Project, "project not found");
1309 end Imported_Or_Extended_Project_From;
1315 function Package_From
1316 (Project : Project_Id;
1317 Shared : Shared_Project_Tree_Data_Access;
1318 With_Name : Name_Id) return Package_Id
1320 Result : Package_Id := Project.Decl.Packages;
1323 -- Check the name of each existing package of Project
1325 while Result /= No_Package
1326 and then Shared.Packages.Table (Result).Name /= With_Name
1328 Result := Shared.Packages.Table (Result).Next;
1331 if Result = No_Package then
1333 -- Should never happen
1336 ("package """ & Get_Name_String (With_Name) & """ not found");
1337 raise Program_Error;
1349 (In_Tree : Project_Tree_Ref;
1350 Project : out Project_Id;
1351 Packages_To_Check : String_List_Access;
1352 Success : out Boolean;
1353 From_Project_Node : Project_Node_Id;
1354 From_Project_Node_Tree : Project_Node_Tree_Ref;
1355 Env : in out Prj.Tree.Environment;
1356 Reset_Tree : Boolean := True)
1359 Process_Project_Tree_Phase_1
1360 (In_Tree => In_Tree,
1363 From_Project_Node => From_Project_Node,
1364 From_Project_Node_Tree => From_Project_Node_Tree,
1366 Packages_To_Check => Packages_To_Check,
1367 Reset_Tree => Reset_Tree);
1369 if Project_Qualifier_Of
1370 (From_Project_Node, From_Project_Node_Tree) /= Configuration
1372 Process_Project_Tree_Phase_2
1373 (In_Tree => In_Tree,
1376 From_Project_Node => From_Project_Node,
1377 From_Project_Node_Tree => From_Project_Node_Tree,
1382 -------------------------------
1383 -- Process_Declarative_Items --
1384 -------------------------------
1386 procedure Process_Declarative_Items
1387 (Project : Project_Id;
1388 In_Tree : Project_Tree_Ref;
1389 From_Project_Node : Project_Node_Id;
1390 Node_Tree : Project_Node_Tree_Ref;
1391 Env : Prj.Tree.Environment;
1393 Item : Project_Node_Id;
1394 Child_Env : in out Prj.Tree.Environment)
1396 Shared : constant Shared_Project_Tree_Data_Access := In_Tree.Shared;
1398 procedure Check_Or_Set_Typed_Variable
1399 (Value : in out Variable_Value;
1400 Declaration : Project_Node_Id);
1401 -- Check whether Value is valid for this typed variable declaration. If
1402 -- it is an error, the behavior depends on the flags: either an error is
1403 -- reported, or a warning, or nothing. In the last two cases, the value
1404 -- of the variable is set to a valid value, replacing Value.
1406 procedure Process_Package_Declaration
1407 (Current_Item : Project_Node_Id);
1408 procedure Process_Attribute_Declaration
1409 (Current : Project_Node_Id);
1410 procedure Process_Case_Construction
1411 (Current_Item : Project_Node_Id);
1412 procedure Process_Associative_Array
1413 (Current_Item : Project_Node_Id);
1414 procedure Process_Expression
1415 (Current : Project_Node_Id);
1416 procedure Process_Expression_For_Associative_Array
1417 (Current : Project_Node_Id;
1418 New_Value : Variable_Value);
1419 procedure Process_Expression_Variable_Decl
1420 (Current_Item : Project_Node_Id;
1421 New_Value : Variable_Value);
1422 -- Process the various declarative items
1424 ---------------------------------
1425 -- Check_Or_Set_Typed_Variable --
1426 ---------------------------------
1428 procedure Check_Or_Set_Typed_Variable
1429 (Value : in out Variable_Value;
1430 Declaration : Project_Node_Id)
1432 Loc : constant Source_Ptr := Location_Of (Declaration, Node_Tree);
1434 Reset_Value : Boolean := False;
1435 Current_String : Project_Node_Id;
1438 -- Report an error for an empty string
1440 if Value.Value = Empty_String then
1441 Error_Msg_Name_1 := Name_Of (Declaration, Node_Tree);
1443 case Env.Flags.Allow_Invalid_External is
1446 (Env.Flags, "no value defined for %%", Loc, Project);
1448 Reset_Value := True;
1450 (Env.Flags, "?no value defined for %%", Loc, Project);
1452 Reset_Value := True;
1456 -- Loop through all the valid strings for the
1457 -- string type and compare to the string value.
1460 First_Literal_String
1461 (String_Type_Of (Declaration, Node_Tree), Node_Tree);
1463 while Present (Current_String)
1465 String_Value_Of (Current_String, Node_Tree) /= Value.Value
1468 Next_Literal_String (Current_String, Node_Tree);
1471 -- Report error if string value is not one for the string type
1473 if No (Current_String) then
1474 Error_Msg_Name_1 := Value.Value;
1475 Error_Msg_Name_2 := Name_Of (Declaration, Node_Tree);
1477 case Env.Flags.Allow_Invalid_External is
1480 (Env.Flags, "value %% is illegal for typed string %%",
1485 (Env.Flags, "?value %% is illegal for typed string %%",
1487 Reset_Value := True;
1490 Reset_Value := True;
1497 First_Literal_String
1498 (String_Type_Of (Declaration, Node_Tree), Node_Tree);
1499 Value.Value := String_Value_Of (Current_String, Node_Tree);
1501 end Check_Or_Set_Typed_Variable;
1503 ---------------------------------
1504 -- Process_Package_Declaration --
1505 ---------------------------------
1507 procedure Process_Package_Declaration
1508 (Current_Item : Project_Node_Id)
1511 -- Do not process a package declaration that should be ignored
1513 if Expression_Kind_Of (Current_Item, Node_Tree) /= Ignored then
1515 -- Create the new package
1517 Package_Table.Increment_Last (Shared.Packages);
1520 New_Pkg : constant Package_Id :=
1521 Package_Table.Last (Shared.Packages);
1522 The_New_Package : Package_Element;
1524 Project_Of_Renamed_Package : constant Project_Node_Id :=
1525 Project_Of_Renamed_Package_Of
1526 (Current_Item, Node_Tree);
1529 -- Set the name of the new package
1531 The_New_Package.Name := Name_Of (Current_Item, Node_Tree);
1533 -- Insert the new package in the appropriate list
1535 if Pkg /= No_Package then
1536 The_New_Package.Next :=
1537 Shared.Packages.Table (Pkg).Decl.Packages;
1538 Shared.Packages.Table (Pkg).Decl.Packages := New_Pkg;
1541 The_New_Package.Next := Project.Decl.Packages;
1542 Project.Decl.Packages := New_Pkg;
1545 Shared.Packages.Table (New_Pkg) := The_New_Package;
1547 if Present (Project_Of_Renamed_Package) then
1549 -- Renamed or extending package
1552 Project_Name : constant Name_Id :=
1553 Name_Of (Project_Of_Renamed_Package,
1556 Renamed_Project : constant Project_Id :=
1557 Imported_Or_Extended_Project_From
1558 (Project, Project_Name);
1560 Renamed_Package : constant Package_Id :=
1562 (Renamed_Project, Shared,
1563 Name_Of (Current_Item, Node_Tree));
1566 -- For a renamed package, copy the declarations of the
1567 -- renamed package, but set all the locations to the
1568 -- location of the package name in the renaming
1571 Copy_Package_Declarations
1572 (From => Shared.Packages.Table
1573 (Renamed_Package).Decl,
1574 To => Shared.Packages.Table (New_Pkg).Decl,
1575 New_Loc => Location_Of (Current_Item, Node_Tree),
1576 Restricted => False,
1581 -- Set the default values of the attributes
1586 Name_Id (Project.Directory.Name),
1588 Shared.Packages.Table (New_Pkg).Decl,
1590 (Package_Id_Of (Current_Item, Node_Tree)),
1591 Project_Level => False);
1594 -- Process declarative items (nothing to do when the package is
1595 -- renaming, as the first declarative item is null).
1597 Process_Declarative_Items
1598 (Project => Project,
1600 From_Project_Node => From_Project_Node,
1601 Node_Tree => Node_Tree,
1605 First_Declarative_Item_Of (Current_Item, Node_Tree),
1606 Child_Env => Child_Env);
1609 end Process_Package_Declaration;
1611 -------------------------------
1612 -- Process_Associative_Array --
1613 -------------------------------
1615 procedure Process_Associative_Array
1616 (Current_Item : Project_Node_Id)
1618 Current_Item_Name : constant Name_Id :=
1619 Name_Of (Current_Item, Node_Tree);
1620 -- The name of the attribute
1622 Current_Location : constant Source_Ptr :=
1623 Location_Of (Current_Item, Node_Tree);
1625 New_Array : Array_Id;
1626 -- The new associative array created
1628 Orig_Array : Array_Id;
1629 -- The associative array value
1631 Orig_Project_Name : Name_Id := No_Name;
1632 -- The name of the project where the associative array
1635 Orig_Project : Project_Id := No_Project;
1636 -- The id of the project where the associative array
1639 Orig_Package_Name : Name_Id := No_Name;
1640 -- The name of the package, if any, where the associative array value
1643 Orig_Package : Package_Id := No_Package;
1644 -- The id of the package, if any, where the associative array value
1647 New_Element : Array_Element_Id := No_Array_Element;
1648 -- Id of a new array element created
1650 Prev_Element : Array_Element_Id := No_Array_Element;
1651 -- Last new element id created
1653 Orig_Element : Array_Element_Id := No_Array_Element;
1654 -- Current array element in original associative array
1656 Next_Element : Array_Element_Id := No_Array_Element;
1657 -- Id of the array element that follows the new element. This is not
1658 -- always nil, because values for the associative array attribute may
1659 -- already have been declared, and the array elements declared are
1665 -- First find if the associative array attribute already has elements
1668 if Pkg /= No_Package then
1669 New_Array := Shared.Packages.Table (Pkg).Decl.Arrays;
1671 New_Array := Project.Decl.Arrays;
1674 while New_Array /= No_Array
1675 and then Shared.Arrays.Table (New_Array).Name /= Current_Item_Name
1677 New_Array := Shared.Arrays.Table (New_Array).Next;
1680 -- If the attribute has never been declared add new entry in the
1681 -- arrays of the project/package and link it.
1683 if New_Array = No_Array then
1684 Array_Table.Increment_Last (Shared.Arrays);
1685 New_Array := Array_Table.Last (Shared.Arrays);
1687 if Pkg /= No_Package then
1688 Shared.Arrays.Table (New_Array) :=
1689 (Name => Current_Item_Name,
1690 Location => Current_Location,
1691 Value => No_Array_Element,
1692 Next => Shared.Packages.Table (Pkg).Decl.Arrays);
1694 Shared.Packages.Table (Pkg).Decl.Arrays := New_Array;
1697 Shared.Arrays.Table (New_Array) :=
1698 (Name => Current_Item_Name,
1699 Location => Current_Location,
1700 Value => No_Array_Element,
1701 Next => Project.Decl.Arrays);
1703 Project.Decl.Arrays := New_Array;
1707 -- Find the project where the value is declared
1709 Orig_Project_Name :=
1711 (Associative_Project_Of (Current_Item, Node_Tree), Node_Tree);
1713 Prj := In_Tree.Projects;
1714 while Prj /= null loop
1715 if Prj.Project.Name = Orig_Project_Name then
1716 Orig_Project := Prj.Project;
1722 pragma Assert (Orig_Project /= No_Project,
1723 "original project not found");
1725 if No (Associative_Package_Of (Current_Item, Node_Tree)) then
1726 Orig_Array := Orig_Project.Decl.Arrays;
1729 -- If in a package, find the package where the value is declared
1731 Orig_Package_Name :=
1733 (Associative_Package_Of (Current_Item, Node_Tree), Node_Tree);
1735 Orig_Package := Orig_Project.Decl.Packages;
1736 pragma Assert (Orig_Package /= No_Package,
1737 "original package not found");
1739 while Shared.Packages.Table
1740 (Orig_Package).Name /= Orig_Package_Name
1742 Orig_Package := Shared.Packages.Table (Orig_Package).Next;
1743 pragma Assert (Orig_Package /= No_Package,
1744 "original package not found");
1747 Orig_Array := Shared.Packages.Table (Orig_Package).Decl.Arrays;
1750 -- Now look for the array
1752 while Orig_Array /= No_Array
1753 and then Shared.Arrays.Table (Orig_Array).Name /= Current_Item_Name
1755 Orig_Array := Shared.Arrays.Table (Orig_Array).Next;
1758 if Orig_Array = No_Array then
1761 "associative array value not found",
1762 Location_Of (Current_Item, Node_Tree),
1766 Orig_Element := Shared.Arrays.Table (Orig_Array).Value;
1768 -- Copy each array element
1770 while Orig_Element /= No_Array_Element loop
1772 -- Case of first element
1774 if Prev_Element = No_Array_Element then
1776 -- And there is no array element declared yet, create a new
1777 -- first array element.
1779 if Shared.Arrays.Table (New_Array).Value =
1782 Array_Element_Table.Increment_Last
1783 (Shared.Array_Elements);
1784 New_Element := Array_Element_Table.Last
1785 (Shared.Array_Elements);
1786 Shared.Arrays.Table (New_Array).Value := New_Element;
1787 Next_Element := No_Array_Element;
1789 -- Otherwise, the new element is the first
1792 New_Element := Shared.Arrays.Table (New_Array).Value;
1794 Shared.Array_Elements.Table (New_Element).Next;
1797 -- Otherwise, reuse an existing element, or create
1798 -- one if necessary.
1802 Shared.Array_Elements.Table (Prev_Element).Next;
1804 if Next_Element = No_Array_Element then
1805 Array_Element_Table.Increment_Last
1806 (Shared.Array_Elements);
1807 New_Element := Array_Element_Table.Last
1808 (Shared.Array_Elements);
1809 Shared.Array_Elements.Table (Prev_Element).Next :=
1813 New_Element := Next_Element;
1815 Shared.Array_Elements.Table (New_Element).Next;
1819 -- Copy the value of the element
1821 Shared.Array_Elements.Table (New_Element) :=
1822 Shared.Array_Elements.Table (Orig_Element);
1823 Shared.Array_Elements.Table (New_Element).Value.Project
1826 -- Adjust the Next link
1828 Shared.Array_Elements.Table (New_Element).Next := Next_Element;
1830 -- Adjust the previous id for the next element
1832 Prev_Element := New_Element;
1834 -- Go to the next element in the original array
1836 Orig_Element := Shared.Array_Elements.Table (Orig_Element).Next;
1839 -- Make sure that the array ends here, in case there previously a
1840 -- greater number of elements.
1842 Shared.Array_Elements.Table (New_Element).Next := No_Array_Element;
1844 end Process_Associative_Array;
1846 ----------------------------------------------
1847 -- Process_Expression_For_Associative_Array --
1848 ----------------------------------------------
1850 procedure Process_Expression_For_Associative_Array
1851 (Current : Project_Node_Id;
1852 New_Value : Variable_Value)
1854 Name : constant Name_Id := Name_Of (Current, Node_Tree);
1855 Current_Location : constant Source_Ptr :=
1856 Location_Of (Current, Node_Tree);
1858 Index_Name : Name_Id :=
1859 Associative_Array_Index_Of (Current, Node_Tree);
1861 Source_Index : constant Int :=
1862 Source_Index_Of (Current, Node_Tree);
1864 The_Array : Array_Id;
1865 Elem : Array_Element_Id := No_Array_Element;
1868 if Index_Name /= All_Other_Names then
1869 Index_Name := Get_Attribute_Index (Node_Tree, Current, Index_Name);
1872 -- Look for the array in the appropriate list
1874 if Pkg /= No_Package then
1875 The_Array := Shared.Packages.Table (Pkg).Decl.Arrays;
1877 The_Array := Project.Decl.Arrays;
1880 while The_Array /= No_Array
1881 and then Shared.Arrays.Table (The_Array).Name /= Name
1883 The_Array := Shared.Arrays.Table (The_Array).Next;
1886 -- If the array cannot be found, create a new entry in the list.
1887 -- As The_Array_Element is initialized to No_Array_Element, a new
1888 -- element will be created automatically later
1890 if The_Array = No_Array then
1891 Array_Table.Increment_Last (Shared.Arrays);
1892 The_Array := Array_Table.Last (Shared.Arrays);
1894 if Pkg /= No_Package then
1895 Shared.Arrays.Table (The_Array) :=
1897 Location => Current_Location,
1898 Value => No_Array_Element,
1899 Next => Shared.Packages.Table (Pkg).Decl.Arrays);
1901 Shared.Packages.Table (Pkg).Decl.Arrays := The_Array;
1904 Shared.Arrays.Table (The_Array) :=
1906 Location => Current_Location,
1907 Value => No_Array_Element,
1908 Next => Project.Decl.Arrays);
1910 Project.Decl.Arrays := The_Array;
1914 Elem := Shared.Arrays.Table (The_Array).Value;
1917 -- Look in the list, if any, to find an element with the same index
1918 -- and same source index.
1920 while Elem /= No_Array_Element
1922 (Shared.Array_Elements.Table (Elem).Index /= Index_Name
1924 Shared.Array_Elements.Table (Elem).Src_Index /= Source_Index)
1926 Elem := Shared.Array_Elements.Table (Elem).Next;
1929 -- If no such element were found, create a new one
1930 -- and insert it in the element list, with the
1933 if Elem = No_Array_Element then
1934 Array_Element_Table.Increment_Last (Shared.Array_Elements);
1935 Elem := Array_Element_Table.Last (Shared.Array_Elements);
1937 Shared.Array_Elements.Table
1939 (Index => Index_Name,
1940 Restricted => False,
1941 Src_Index => Source_Index,
1942 Index_Case_Sensitive =>
1943 not Case_Insensitive (Current, Node_Tree),
1945 Next => Shared.Arrays.Table (The_Array).Value);
1947 Shared.Arrays.Table (The_Array).Value := Elem;
1950 -- An element with the same index already exists, just replace its
1951 -- value with the new one.
1953 Shared.Array_Elements.Table (Elem).Value := New_Value;
1956 if Name = Snames.Name_External then
1957 if In_Tree.Is_Root_Tree then
1958 Add (Child_Env.External,
1959 External_Name => Get_Name_String (Index_Name),
1960 Value => Get_Name_String (New_Value.Value),
1961 Source => From_External_Attribute);
1963 External_Name => Get_Name_String (Index_Name),
1964 Value => Get_Name_String (New_Value.Value),
1965 Source => From_External_Attribute);
1967 if Current_Verbosity = High then
1969 ("'for External' has no effect except in root aggregate ("
1970 & Get_Name_String (Index_Name) & ")", New_Value.Value);
1974 end Process_Expression_For_Associative_Array;
1976 --------------------------------------
1977 -- Process_Expression_Variable_Decl --
1978 --------------------------------------
1980 procedure Process_Expression_Variable_Decl
1981 (Current_Item : Project_Node_Id;
1982 New_Value : Variable_Value)
1984 Name : constant Name_Id := Name_Of (Current_Item, Node_Tree);
1986 Is_Attribute : constant Boolean :=
1987 Kind_Of (Current_Item, Node_Tree) =
1988 N_Attribute_Declaration;
1990 Var : Variable_Id := No_Variable;
1993 -- First, find the list where to find the variable or attribute
1995 if Is_Attribute then
1996 if Pkg /= No_Package then
1997 Var := Shared.Packages.Table (Pkg).Decl.Attributes;
1999 Var := Project.Decl.Attributes;
2003 if Pkg /= No_Package then
2004 Var := Shared.Packages.Table (Pkg).Decl.Variables;
2006 Var := Project.Decl.Variables;
2010 -- Loop through the list, to find if it has already been declared
2012 while Var /= No_Variable
2013 and then Shared.Variable_Elements.Table (Var).Name /= Name
2015 Var := Shared.Variable_Elements.Table (Var).Next;
2018 -- If it has not been declared, create a new entry in the list
2020 if Var = No_Variable then
2022 -- All single string attribute should already have been declared
2023 -- with a default empty string value.
2027 "illegal attribute declaration for " & Get_Name_String (Name));
2029 Variable_Element_Table.Increment_Last (Shared.Variable_Elements);
2030 Var := Variable_Element_Table.Last (Shared.Variable_Elements);
2032 -- Put the new variable in the appropriate list
2034 if Pkg /= No_Package then
2035 Shared.Variable_Elements.Table (Var) :=
2036 (Next => Shared.Packages.Table (Pkg).Decl.Variables,
2038 Value => New_Value);
2039 Shared.Packages.Table (Pkg).Decl.Variables := Var;
2042 Shared.Variable_Elements.Table (Var) :=
2043 (Next => Project.Decl.Variables,
2045 Value => New_Value);
2046 Project.Decl.Variables := Var;
2049 -- If the variable/attribute has already been declared, just
2050 -- change the value.
2053 Shared.Variable_Elements.Table (Var).Value := New_Value;
2056 if Is_Attribute and then Name = Snames.Name_Project_Path then
2057 if In_Tree.Is_Root_Tree then
2059 Val : String_List_Id := New_Value.Values;
2061 while Val /= Nil_String loop
2062 Prj.Env.Add_Directories
2063 (Child_Env.Project_Path,
2065 (Shared.String_Elements.Table (Val).Value));
2066 Val := Shared.String_Elements.Table (Val).Next;
2071 if Current_Verbosity = High then
2073 ("'for Project_Path' has no effect except in"
2074 & " root aggregate");
2078 end Process_Expression_Variable_Decl;
2080 ------------------------
2081 -- Process_Expression --
2082 ------------------------
2084 procedure Process_Expression (Current : Project_Node_Id) is
2085 New_Value : Variable_Value :=
2087 (Project => Project,
2089 From_Project_Node => From_Project_Node,
2090 From_Project_Node_Tree => Node_Tree,
2095 (Expression_Of (Current, Node_Tree), Node_Tree),
2097 Expression_Kind_Of (Current, Node_Tree));
2100 -- Process a typed variable declaration
2102 if Kind_Of (Current, Node_Tree) = N_Typed_Variable_Declaration then
2103 Check_Or_Set_Typed_Variable (New_Value, Current);
2106 if Kind_Of (Current, Node_Tree) /= N_Attribute_Declaration
2107 or else Associative_Array_Index_Of (Current, Node_Tree) = No_Name
2109 Process_Expression_Variable_Decl (Current, New_Value);
2111 Process_Expression_For_Associative_Array (Current, New_Value);
2113 end Process_Expression;
2115 -----------------------------------
2116 -- Process_Attribute_Declaration --
2117 -----------------------------------
2119 procedure Process_Attribute_Declaration (Current : Project_Node_Id) is
2121 if Expression_Of (Current, Node_Tree) = Empty_Node then
2122 Process_Associative_Array (Current);
2124 Process_Expression (Current);
2126 end Process_Attribute_Declaration;
2128 -------------------------------
2129 -- Process_Case_Construction --
2130 -------------------------------
2132 procedure Process_Case_Construction
2133 (Current_Item : Project_Node_Id)
2135 The_Project : Project_Id := Project;
2136 -- The id of the project of the case variable
2138 The_Package : Package_Id := Pkg;
2139 -- The id of the package, if any, of the case variable
2141 The_Variable : Variable_Value := Nil_Variable_Value;
2142 -- The case variable
2144 Case_Value : Name_Id := No_Name;
2145 -- The case variable value
2147 Case_Item : Project_Node_Id := Empty_Node;
2148 Choice_String : Project_Node_Id := Empty_Node;
2149 Decl_Item : Project_Node_Id := Empty_Node;
2153 Variable_Node : constant Project_Node_Id :=
2154 Case_Variable_Reference_Of
2158 Var_Id : Variable_Id := No_Variable;
2159 Name : Name_Id := No_Name;
2162 -- If a project was specified for the case variable, get its id
2164 if Present (Project_Node_Of (Variable_Node, Node_Tree)) then
2167 (Project_Node_Of (Variable_Node, Node_Tree), Node_Tree);
2169 Imported_Or_Extended_Project_From (Project, Name);
2172 -- If a package was specified for the case variable, get its id
2174 if Present (Package_Node_Of (Variable_Node, Node_Tree)) then
2177 (Package_Node_Of (Variable_Node, Node_Tree), Node_Tree);
2178 The_Package := Package_From (The_Project, Shared, Name);
2181 Name := Name_Of (Variable_Node, Node_Tree);
2183 -- First, look for the case variable into the package, if any
2185 if The_Package /= No_Package then
2186 Name := Name_Of (Variable_Node, Node_Tree);
2188 Var_Id := Shared.Packages.Table (The_Package).Decl.Variables;
2189 while Var_Id /= No_Variable
2190 and then Shared.Variable_Elements.Table (Var_Id).Name /= Name
2192 Var_Id := Shared.Variable_Elements.Table (Var_Id).Next;
2196 -- If not found in the package, or if there is no package, look at
2197 -- the project level.
2199 if Var_Id = No_Variable
2200 and then No (Package_Node_Of (Variable_Node, Node_Tree))
2202 Var_Id := The_Project.Decl.Variables;
2203 while Var_Id /= No_Variable
2204 and then Shared.Variable_Elements.Table (Var_Id).Name /= Name
2206 Var_Id := Shared.Variable_Elements.Table (Var_Id).Next;
2210 if Var_Id = No_Variable then
2212 -- Should never happen, because this has already been checked
2216 ("variable """ & Get_Name_String (Name) & """ not found");
2217 raise Program_Error;
2220 -- Get the case variable
2222 The_Variable := Shared.Variable_Elements. Table (Var_Id).Value;
2224 if The_Variable.Kind /= Single then
2226 -- Should never happen, because this has already been checked
2229 Write_Line ("variable""" & Get_Name_String (Name) &
2230 """ is not a single string variable");
2231 raise Program_Error;
2234 -- Get the case variable value
2236 Case_Value := The_Variable.Value;
2239 -- Now look into all the case items of the case construction
2241 Case_Item := First_Case_Item_Of (Current_Item, Node_Tree);
2244 while Present (Case_Item) loop
2245 Choice_String := First_Choice_Of (Case_Item, Node_Tree);
2247 -- When Choice_String is nil, it means that it is the
2248 -- "when others =>" alternative.
2250 if No (Choice_String) then
2251 Decl_Item := First_Declarative_Item_Of (Case_Item, Node_Tree);
2252 exit Case_Item_Loop;
2255 -- Look into all the alternative of this case item
2258 while Present (Choice_String) loop
2259 if Case_Value = String_Value_Of (Choice_String, Node_Tree) then
2261 First_Declarative_Item_Of (Case_Item, Node_Tree);
2262 exit Case_Item_Loop;
2265 Choice_String := Next_Literal_String (Choice_String, Node_Tree);
2266 end loop Choice_Loop;
2268 Case_Item := Next_Case_Item (Case_Item, Node_Tree);
2269 end loop Case_Item_Loop;
2271 -- If there is an alternative, then we process it
2273 if Present (Decl_Item) then
2274 Process_Declarative_Items
2275 (Project => Project,
2277 From_Project_Node => From_Project_Node,
2278 Node_Tree => Node_Tree,
2282 Child_Env => Child_Env);
2284 end Process_Case_Construction;
2288 Current, Decl : Project_Node_Id;
2289 Kind : Project_Node_Kind;
2291 -- Start of processing for Process_Declarative_Items
2295 while Present (Decl) loop
2296 Current := Current_Item_Node (Decl, Node_Tree);
2297 Decl := Next_Declarative_Item (Decl, Node_Tree);
2298 Kind := Kind_Of (Current, Node_Tree);
2301 when N_Package_Declaration =>
2302 Process_Package_Declaration (Current);
2304 -- Nothing to process for string type declaration
2306 when N_String_Type_Declaration =>
2309 when N_Attribute_Declaration |
2310 N_Typed_Variable_Declaration |
2311 N_Variable_Declaration =>
2312 Process_Attribute_Declaration (Current);
2314 when N_Case_Construction =>
2315 Process_Case_Construction (Current);
2318 Write_Line ("Illegal declarative item: " & Kind'Img);
2319 raise Program_Error;
2322 end Process_Declarative_Items;
2324 ----------------------------------
2325 -- Process_Project_Tree_Phase_1 --
2326 ----------------------------------
2328 procedure Process_Project_Tree_Phase_1
2329 (In_Tree : Project_Tree_Ref;
2330 Project : out Project_Id;
2331 Packages_To_Check : String_List_Access;
2332 Success : out Boolean;
2333 From_Project_Node : Project_Node_Id;
2334 From_Project_Node_Tree : Project_Node_Tree_Ref;
2335 Env : in out Prj.Tree.Environment;
2336 Reset_Tree : Boolean := True)
2341 -- Make sure there are no projects in the data structure
2343 Free_List (In_Tree.Projects, Free_Project => True);
2346 Processed_Projects.Reset;
2348 -- And process the main project and all of the projects it depends on,
2351 Debug_Increase_Indent ("Process tree, phase 1");
2354 (Project => Project,
2356 Packages_To_Check => Packages_To_Check,
2357 From_Project_Node => From_Project_Node,
2358 From_Project_Node_Tree => From_Project_Node_Tree,
2360 Extended_By => No_Project);
2363 Total_Errors_Detected = 0
2365 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2367 if Current_Verbosity = High then
2368 Debug_Decrease_Indent
2369 ("Done Process tree, phase 1, Success=" & Success'Img);
2371 end Process_Project_Tree_Phase_1;
2373 ----------------------------------
2374 -- Process_Project_Tree_Phase_2 --
2375 ----------------------------------
2377 procedure Process_Project_Tree_Phase_2
2378 (In_Tree : Project_Tree_Ref;
2379 Project : Project_Id;
2380 Success : out Boolean;
2381 From_Project_Node : Project_Node_Id;
2382 From_Project_Node_Tree : Project_Node_Tree_Ref;
2385 Obj_Dir : Path_Name_Type;
2386 Extending : Project_Id;
2387 Extending2 : Project_Id;
2390 -- Start of processing for Process_Project_Tree_Phase_2
2395 Debug_Increase_Indent ("Process tree, phase 2", Project.Name);
2397 if Project /= No_Project then
2398 Check (In_Tree, Project, From_Project_Node_Tree, Env.Flags);
2401 -- If main project is an extending all project, set object directory of
2402 -- all virtual extending projects to object directory of main project.
2404 if Project /= No_Project
2405 and then Is_Extending_All (From_Project_Node, From_Project_Node_Tree)
2408 Object_Dir : constant Path_Information := Project.Object_Directory;
2411 Prj := In_Tree.Projects;
2412 while Prj /= null loop
2413 if Prj.Project.Virtual then
2414 Prj.Project.Object_Directory := Object_Dir;
2422 -- Check that no extending project shares its object directory with
2423 -- the project(s) it extends.
2425 if Project /= No_Project then
2426 Prj := In_Tree.Projects;
2427 while Prj /= null loop
2428 Extending := Prj.Project.Extended_By;
2430 if Extending /= No_Project then
2431 Obj_Dir := Prj.Project.Object_Directory.Name;
2433 -- Check that a project being extended does not share its
2434 -- object directory with any project that extends it, directly
2435 -- or indirectly, including a virtual extending project.
2437 -- Start with the project directly extending it
2439 Extending2 := Extending;
2440 while Extending2 /= No_Project loop
2441 if Has_Ada_Sources (Extending2)
2442 and then Extending2.Object_Directory.Name = Obj_Dir
2444 if Extending2.Virtual then
2445 Error_Msg_Name_1 := Prj.Project.Display_Name;
2448 "project %% cannot be extended by a virtual" &
2449 " project with the same object directory",
2450 Prj.Project.Location, Project);
2453 Error_Msg_Name_1 := Extending2.Display_Name;
2454 Error_Msg_Name_2 := Prj.Project.Display_Name;
2457 "project %% cannot extend project %%",
2458 Extending2.Location, Project);
2461 "\they share the same object directory",
2462 Extending2.Location, Project);
2466 -- Continue with the next extending project, if any
2468 Extending2 := Extending2.Extended_By;
2476 Debug_Decrease_Indent ("Done Process tree, phase 2");
2478 Success := Total_Errors_Detected = 0
2480 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2481 end Process_Project_Tree_Phase_2;
2483 -----------------------
2484 -- Recursive_Process --
2485 -----------------------
2487 procedure Recursive_Process
2488 (In_Tree : Project_Tree_Ref;
2489 Project : out Project_Id;
2490 Packages_To_Check : String_List_Access;
2491 From_Project_Node : Project_Node_Id;
2492 From_Project_Node_Tree : Project_Node_Tree_Ref;
2493 Env : in out Prj.Tree.Environment;
2494 Extended_By : Project_Id)
2496 Shared : constant Shared_Project_Tree_Data_Access := In_Tree.Shared;
2498 Child_Env : Prj.Tree.Environment;
2499 -- Only used for the root aggregate project (if any). This is left
2500 -- uninitialized otherwise.
2502 procedure Process_Imported_Projects
2503 (Imported : in out Project_List;
2504 Limited_With : Boolean);
2505 -- Process imported projects. If Limited_With is True, then only
2506 -- projects processed through a "limited with" are processed, otherwise
2507 -- only projects imported through a standard "with" are processed.
2508 -- Imported is the id of the last imported project.
2510 procedure Process_Aggregated_Projects;
2511 -- Process all the projects aggregated in List. This does nothing if the
2512 -- project is not an aggregate project.
2514 procedure Process_Extended_Project;
2515 -- Process the extended project: inherit all packages from the extended
2516 -- project that are not explicitly defined or renamed. Also inherit the
2517 -- languages, if attribute Languages is not explicitly defined.
2519 -------------------------------
2520 -- Process_Imported_Projects --
2521 -------------------------------
2523 procedure Process_Imported_Projects
2524 (Imported : in out Project_List;
2525 Limited_With : Boolean)
2527 With_Clause : Project_Node_Id;
2528 New_Project : Project_Id;
2529 Proj_Node : Project_Node_Id;
2533 First_With_Clause_Of
2534 (From_Project_Node, From_Project_Node_Tree);
2536 while Present (With_Clause) loop
2538 Non_Limited_Project_Node_Of
2539 (With_Clause, From_Project_Node_Tree);
2540 New_Project := No_Project;
2542 if (Limited_With and then No (Proj_Node))
2543 or else (not Limited_With and then Present (Proj_Node))
2546 (In_Tree => In_Tree,
2547 Project => New_Project,
2548 Packages_To_Check => Packages_To_Check,
2549 From_Project_Node =>
2550 Project_Node_Of (With_Clause, From_Project_Node_Tree),
2551 From_Project_Node_Tree => From_Project_Node_Tree,
2553 Extended_By => No_Project);
2555 -- Imported is the id of the last imported project. If
2556 -- it is nil, then this imported project is our first.
2558 if Imported = null then
2559 Project.Imported_Projects :=
2560 new Project_List_Element'
2561 (Project => New_Project,
2563 Imported := Project.Imported_Projects;
2565 Imported.Next := new Project_List_Element'
2566 (Project => New_Project,
2568 Imported := Imported.Next;
2573 Next_With_Clause_Of (With_Clause, From_Project_Node_Tree);
2575 end Process_Imported_Projects;
2577 ---------------------------------
2578 -- Process_Aggregated_Projects --
2579 ---------------------------------
2581 procedure Process_Aggregated_Projects is
2582 List : Aggregated_Project_List;
2583 Loaded_Project : Prj.Tree.Project_Node_Id;
2584 Success : Boolean := True;
2585 Tree : Project_Tree_Ref;
2588 if Project.Qualifier not in Aggregate_Project then
2592 Debug_Increase_Indent ("Process_Aggregated_Projects", Project.Name);
2594 Prj.Nmsc.Process_Aggregated_Projects
2597 Node_Tree => From_Project_Node_Tree,
2598 Flags => Env.Flags);
2600 List := Project.Aggregated_Projects;
2601 while Success and then List /= null loop
2603 (In_Tree => From_Project_Node_Tree,
2604 Project => Loaded_Project,
2605 Packages_To_Check => Packages_To_Check,
2606 Project_File_Name => Get_Name_String (List.Path),
2607 Errout_Handling => Prj.Part.Never_Finalize,
2608 Current_Directory => Get_Name_String (Project.Directory.Name),
2609 Is_Config_File => False,
2612 Success := not Prj.Tree.No (Loaded_Project);
2615 List.Tree := new Project_Tree_Data (Is_Root_Tree => False);
2616 Prj.Initialize (List.Tree);
2617 List.Tree.Shared := In_Tree.Shared;
2619 -- In aggregate library, aggregated projects are parsed using
2620 -- the aggregate library tree.
2622 if Project.Qualifier = Aggregate_Library then
2628 -- We can only do the phase 1 of the processing, since we do
2629 -- not have access to the configuration file yet (this is
2630 -- called when doing phase 1 of the processing for the root
2631 -- aggregate project).
2633 if In_Tree.Is_Root_Tree then
2634 Process_Project_Tree_Phase_1
2636 Project => List.Project,
2637 Packages_To_Check => Packages_To_Check,
2639 From_Project_Node => Loaded_Project,
2640 From_Project_Node_Tree => From_Project_Node_Tree,
2642 Reset_Tree => False);
2644 -- use the same environment as the rest of the aggregated
2645 -- projects, ie the one that was setup by the root aggregate
2646 Process_Project_Tree_Phase_1
2648 Project => List.Project,
2649 Packages_To_Check => Packages_To_Check,
2651 From_Project_Node => Loaded_Project,
2652 From_Project_Node_Tree => From_Project_Node_Tree,
2654 Reset_Tree => False);
2658 Debug_Output ("Failed to parse", Name_Id (List.Path));
2664 Debug_Decrease_Indent ("Done Process_Aggregated_Projects");
2665 end Process_Aggregated_Projects;
2667 ------------------------------
2668 -- Process_Extended_Project --
2669 ------------------------------
2671 procedure Process_Extended_Project is
2672 Extended_Pkg : Package_Id;
2673 Current_Pkg : Package_Id;
2674 Element : Package_Element;
2675 First : constant Package_Id := Project.Decl.Packages;
2676 Attribute1 : Variable_Id;
2677 Attribute2 : Variable_Id;
2678 Attr_Value1 : Variable;
2679 Attr_Value2 : Variable;
2682 Extended_Pkg := Project.Extends.Decl.Packages;
2683 while Extended_Pkg /= No_Package loop
2684 Element := Shared.Packages.Table (Extended_Pkg);
2686 Current_Pkg := First;
2687 while Current_Pkg /= No_Package
2689 Shared.Packages.Table (Current_Pkg).Name /= Element.Name
2691 Current_Pkg := Shared.Packages.Table (Current_Pkg).Next;
2694 if Current_Pkg = No_Package then
2695 Package_Table.Increment_Last (Shared.Packages);
2696 Current_Pkg := Package_Table.Last (Shared.Packages);
2697 Shared.Packages.Table (Current_Pkg) :=
2698 (Name => Element.Name,
2699 Decl => No_Declarations,
2700 Parent => No_Package,
2701 Next => Project.Decl.Packages);
2702 Project.Decl.Packages := Current_Pkg;
2703 Copy_Package_Declarations
2704 (From => Element.Decl,
2705 To => Shared.Packages.Table (Current_Pkg).Decl,
2706 New_Loc => No_Location,
2711 Extended_Pkg := Element.Next;
2714 -- Check if attribute Languages is declared in the extending project
2716 Attribute1 := Project.Decl.Attributes;
2717 while Attribute1 /= No_Variable loop
2718 Attr_Value1 := Shared.Variable_Elements. Table (Attribute1);
2719 exit when Attr_Value1.Name = Snames.Name_Languages;
2720 Attribute1 := Attr_Value1.Next;
2723 if Attribute1 = No_Variable or else Attr_Value1.Value.Default then
2725 -- Attribute Languages is not declared in the extending project.
2726 -- Check if it is declared in the project being extended.
2728 Attribute2 := Project.Extends.Decl.Attributes;
2729 while Attribute2 /= No_Variable loop
2730 Attr_Value2 := Shared.Variable_Elements.Table (Attribute2);
2731 exit when Attr_Value2.Name = Snames.Name_Languages;
2732 Attribute2 := Attr_Value2.Next;
2735 if Attribute2 /= No_Variable
2736 and then not Attr_Value2.Value.Default
2738 -- As attribute Languages is declared in the project being
2739 -- extended, copy its value for the extending project.
2741 if Attribute1 = No_Variable then
2742 Variable_Element_Table.Increment_Last
2743 (Shared.Variable_Elements);
2744 Attribute1 := Variable_Element_Table.Last
2745 (Shared.Variable_Elements);
2746 Attr_Value1.Next := Project.Decl.Attributes;
2747 Project.Decl.Attributes := Attribute1;
2750 Attr_Value1.Name := Snames.Name_Languages;
2751 Attr_Value1.Value := Attr_Value2.Value;
2752 Shared.Variable_Elements.Table (Attribute1) := Attr_Value1;
2755 end Process_Extended_Project;
2757 -- Start of processing for Recursive_Process
2760 if No (From_Project_Node) then
2761 Project := No_Project;
2765 Imported : Project_List;
2766 Declaration_Node : Project_Node_Id := Empty_Node;
2768 Name : constant Name_Id :=
2769 Name_Of (From_Project_Node, From_Project_Node_Tree);
2771 Name_Node : constant Tree_Private_Part.Project_Name_And_Node :=
2772 Tree_Private_Part.Projects_Htable.Get
2773 (From_Project_Node_Tree.Projects_HT, Name);
2776 Project := Processed_Projects.Get (Name);
2778 if Project /= No_Project then
2780 -- Make sure that, when a project is extended, the project id
2781 -- of the project extending it is recorded in its data, even
2782 -- when it has already been processed as an imported project.
2783 -- This is for virtually extended projects.
2785 if Extended_By /= No_Project then
2786 Project.Extended_By := Extended_By;
2795 (Project_Qualifier_Of
2796 (From_Project_Node, From_Project_Node_Tree)));
2799 new Project_List_Element'
2800 (Project => Project,
2801 Next => In_Tree.Projects);
2803 Processed_Projects.Set (Name, Project);
2805 Project.Name := Name;
2806 Project.Display_Name := Name_Node.Display_Name;
2807 Get_Name_String (Name);
2809 -- If name starts with the virtual prefix, flag the project as
2810 -- being a virtual extending project.
2812 if Name_Len > Virtual_Prefix'Length
2814 Name_Buffer (1 .. Virtual_Prefix'Length) = Virtual_Prefix
2816 Project.Virtual := True;
2819 Project.Path.Display_Name :=
2820 Path_Name_Of (From_Project_Node, From_Project_Node_Tree);
2821 Get_Name_String (Project.Path.Display_Name);
2822 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2823 Project.Path.Name := Name_Find;
2826 Location_Of (From_Project_Node, From_Project_Node_Tree);
2828 Project.Directory.Display_Name :=
2829 Directory_Of (From_Project_Node, From_Project_Node_Tree);
2830 Get_Name_String (Project.Directory.Display_Name);
2831 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2832 Project.Directory.Name := Name_Find;
2834 Project.Extended_By := Extended_By;
2839 Name_Id (Project.Directory.Name),
2842 Prj.Attr.Attribute_First,
2843 Project_Level => True);
2845 Process_Imported_Projects (Imported, Limited_With => False);
2847 if Project.Qualifier = Aggregate and then In_Tree.Is_Root_Tree then
2848 Initialize_And_Copy (Child_Env, Copy_From => Env);
2850 elsif Project.Qualifier = Aggregate_Library then
2852 -- The child environment is the same as the current one
2857 -- No need to initialize Child_Env, since it will not be
2858 -- used anyway by Process_Declarative_Items (only the root
2859 -- aggregate can modify it, and it is never read anyway).
2865 Project_Declaration_Of
2866 (From_Project_Node, From_Project_Node_Tree);
2869 (In_Tree => In_Tree,
2870 Project => Project.Extends,
2871 Packages_To_Check => Packages_To_Check,
2872 From_Project_Node =>
2874 (Declaration_Node, From_Project_Node_Tree),
2875 From_Project_Node_Tree => From_Project_Node_Tree,
2877 Extended_By => Project);
2879 Process_Declarative_Items
2880 (Project => Project,
2882 From_Project_Node => From_Project_Node,
2883 Node_Tree => From_Project_Node_Tree,
2886 Item => First_Declarative_Item_Of
2887 (Declaration_Node, From_Project_Node_Tree),
2888 Child_Env => Child_Env);
2890 if Project.Extends /= No_Project then
2891 Process_Extended_Project;
2894 Process_Imported_Projects (Imported, Limited_With => True);
2896 if Err_Vars.Total_Errors_Detected = 0 then
2897 Process_Aggregated_Projects;
2899 -- For an aggregate library we add the aggregated projects as
2900 -- imported ones. This is necessary to give visibility to all
2901 -- sources from the aggregates from the aggregated library
2904 if Project.Qualifier = Aggregate_Library then
2906 L : Aggregated_Project_List;
2908 L := Project.Aggregated_Projects;
2909 while L /= null loop
2910 Project.Imported_Projects :=
2911 new Project_List_Element'
2912 (Project => L.Project,
2913 Next => Project.Imported_Projects);
2920 if Project.Qualifier = Aggregate and then In_Tree.Is_Root_Tree then
2925 end Recursive_Process;