Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / ada / prj-proc.adb
blob385e03536d5850125a5d2817d886f7f63c8b18eb
1 ------------------------------------------------------------------------------
3 -- --
4 -- GNAT COMPILER COMPONENTS --
5 -- --
6 -- P R J . P R O C --
7 -- --
8 -- B o d y --
9 -- --
10 -- Copyright (C) 2001-2007, Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 3, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
20 -- http://www.gnu.org/licenses for a complete copy of the license. --
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 Opt; use Opt;
29 with Osint; use Osint;
30 with Output; use Output;
31 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;
35 with Sinput; use Sinput;
36 with Snames;
38 with GNAT.Case_Util; use GNAT.Case_Util;
39 with GNAT.HTable;
41 package body Prj.Proc is
43 Error_Report : Put_Line_Access := null;
45 package Processed_Projects is new GNAT.HTable.Simple_HTable
46 (Header_Num => Header_Num,
47 Element => Project_Id,
48 No_Element => No_Project,
49 Key => Name_Id,
50 Hash => Hash,
51 Equal => "=");
52 -- This hash table contains all processed projects
54 package Unit_Htable is new GNAT.HTable.Simple_HTable
55 (Header_Num => Header_Num,
56 Element => Source_Id,
57 No_Element => No_Source,
58 Key => Name_Id,
59 Hash => Hash,
60 Equal => "=");
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 procedure Add_Attributes
68 (Project : Project_Id;
69 Project_Name : Name_Id;
70 In_Tree : Project_Tree_Ref;
71 Decl : in out Declarations;
72 First : Attribute_Node_Id;
73 Project_Level : Boolean);
74 -- Add all attributes, starting with First, with their default
75 -- values to the package or project with declarations Decl.
77 procedure Check
78 (In_Tree : Project_Tree_Ref;
79 Project : Project_Id;
80 Current_Dir : String;
81 When_No_Sources : Error_Warning);
82 -- Set all projects to not checked, then call Recursive_Check for the
83 -- main project Project. Project is set to No_Project if errors occurred.
84 -- Current_Dir is for optimization purposes, avoiding extra system calls.
86 procedure Copy_Package_Declarations
87 (From : Declarations;
88 To : in out Declarations;
89 New_Loc : Source_Ptr;
90 In_Tree : Project_Tree_Ref);
91 -- Copy a package declaration From to To for a renamed package. Change the
92 -- locations of all the attributes to New_Loc.
94 function Expression
95 (Project : Project_Id;
96 In_Tree : Project_Tree_Ref;
97 From_Project_Node : Project_Node_Id;
98 From_Project_Node_Tree : Project_Node_Tree_Ref;
99 Pkg : Package_Id;
100 First_Term : Project_Node_Id;
101 Kind : Variable_Kind) return Variable_Value;
102 -- From N_Expression project node From_Project_Node, compute the value
103 -- of an expression and return it as a Variable_Value.
105 function Imported_Or_Extended_Project_From
106 (Project : Project_Id;
107 In_Tree : Project_Tree_Ref;
108 With_Name : Name_Id) return Project_Id;
109 -- Find an imported or extended project of Project whose name is With_Name
111 function Package_From
112 (Project : Project_Id;
113 In_Tree : Project_Tree_Ref;
114 With_Name : Name_Id) return Package_Id;
115 -- Find the package of Project whose name is With_Name
117 procedure Process_Declarative_Items
118 (Project : Project_Id;
119 In_Tree : Project_Tree_Ref;
120 From_Project_Node : Project_Node_Id;
121 From_Project_Node_Tree : Project_Node_Tree_Ref;
122 Pkg : Package_Id;
123 Item : Project_Node_Id);
124 -- Process declarative items starting with From_Project_Node, and put them
125 -- in declarations Decl. This is a recursive procedure; it calls itself for
126 -- a package declaration or a case construction.
128 procedure Recursive_Process
129 (In_Tree : Project_Tree_Ref;
130 Project : out Project_Id;
131 From_Project_Node : Project_Node_Id;
132 From_Project_Node_Tree : Project_Node_Tree_Ref;
133 Extended_By : Project_Id);
134 -- Process project with node From_Project_Node in the tree.
135 -- Do nothing if From_Project_Node is Empty_Node.
136 -- If project has already been processed, simply return its project id.
137 -- Otherwise create a new project id, mark it as processed, call itself
138 -- recursively for all imported projects and a extended project, if any.
139 -- Then process the declarative items of the project.
141 procedure Recursive_Check
142 (Project : Project_Id;
143 In_Tree : Project_Tree_Ref;
144 Current_Dir : String;
145 When_No_Sources : Error_Warning);
146 -- If Project is not marked as checked, mark it as checked, call
147 -- Check_Naming_Scheme for the project, then call itself for a
148 -- possible extended project and all the imported projects of Project.
149 -- Current_Dir is for optimization purposes, avoiding extra system calls.
151 ---------
152 -- Add --
153 ---------
155 procedure Add (To_Exp : in out Name_Id; Str : Name_Id) is
156 begin
157 if To_Exp = No_Name or else To_Exp = Empty_String then
159 -- To_Exp is nil or empty. The result is Str
161 To_Exp := Str;
163 -- If Str is nil, then do not change To_Ext
165 elsif Str /= No_Name and then Str /= Empty_String then
166 declare
167 S : constant String := Get_Name_String (Str);
169 begin
170 Get_Name_String (To_Exp);
171 Add_Str_To_Name_Buffer (S);
172 To_Exp := Name_Find;
173 end;
174 end if;
175 end Add;
177 --------------------
178 -- Add_Attributes --
179 --------------------
181 procedure Add_Attributes
182 (Project : Project_Id;
183 Project_Name : Name_Id;
184 In_Tree : Project_Tree_Ref;
185 Decl : in out Declarations;
186 First : Attribute_Node_Id;
187 Project_Level : Boolean)
189 The_Attribute : Attribute_Node_Id := First;
191 begin
192 while The_Attribute /= Empty_Attribute loop
193 if Attribute_Kind_Of (The_Attribute) = Single then
194 declare
195 New_Attribute : Variable_Value;
197 begin
198 case Variable_Kind_Of (The_Attribute) is
200 -- Undefined should not happen
202 when Undefined =>
203 pragma Assert
204 (False, "attribute with an undefined kind");
205 raise Program_Error;
207 -- Single attributes have a default value of empty string
209 when Single =>
210 New_Attribute :=
211 (Project => Project,
212 Kind => Single,
213 Location => No_Location,
214 Default => True,
215 Value => Empty_String,
216 Index => 0);
218 -- Special case of <project>'Name
220 if Project_Level
221 and then Attribute_Name_Of (The_Attribute) =
222 Snames.Name_Name
223 then
224 New_Attribute.Value := Project_Name;
225 end if;
227 -- List attributes have a default value of nil list
229 when List =>
230 New_Attribute :=
231 (Project => Project,
232 Kind => List,
233 Location => No_Location,
234 Default => True,
235 Values => Nil_String);
237 end case;
239 Variable_Element_Table.Increment_Last
240 (In_Tree.Variable_Elements);
241 In_Tree.Variable_Elements.Table
242 (Variable_Element_Table.Last
243 (In_Tree.Variable_Elements)) :=
244 (Next => Decl.Attributes,
245 Name => Attribute_Name_Of (The_Attribute),
246 Value => New_Attribute);
247 Decl.Attributes := Variable_Element_Table.Last
248 (In_Tree.Variable_Elements);
249 end;
250 end if;
252 The_Attribute := Next_Attribute (After => The_Attribute);
253 end loop;
254 end Add_Attributes;
256 -----------
257 -- Check --
258 -----------
260 procedure Check
261 (In_Tree : Project_Tree_Ref;
262 Project : Project_Id;
263 Current_Dir : String;
264 When_No_Sources : Error_Warning)
266 begin
267 -- Make sure that all projects are marked as not checked
269 for Index in Project_Table.First ..
270 Project_Table.Last (In_Tree.Projects)
271 loop
272 In_Tree.Projects.Table (Index).Checked := False;
273 end loop;
275 Recursive_Check (Project, In_Tree, Current_Dir, When_No_Sources);
277 -- Set the Other_Part field for the units
279 declare
280 Source1 : Source_Id;
281 Name : Name_Id;
282 Source2 : Source_Id;
284 begin
285 Unit_Htable.Reset;
287 Source1 := In_Tree.First_Source;
288 while Source1 /= No_Source loop
289 Name := In_Tree.Sources.Table (Source1).Unit;
291 if Name /= No_Name then
292 Source2 := Unit_Htable.Get (Name);
294 if Source2 = No_Source then
295 Unit_Htable.Set (K => Name, E => Source1);
297 else
298 Unit_Htable.Remove (Name);
299 In_Tree.Sources.Table (Source1).Other_Part := Source2;
300 In_Tree.Sources.Table (Source2).Other_Part := Source1;
301 end if;
302 end if;
304 Source1 := In_Tree.Sources.Table (Source1).Next_In_Sources;
305 end loop;
306 end;
307 end Check;
309 -------------------------------
310 -- Copy_Package_Declarations --
311 -------------------------------
313 procedure Copy_Package_Declarations
314 (From : Declarations;
315 To : in out Declarations;
316 New_Loc : Source_Ptr;
317 In_Tree : Project_Tree_Ref)
319 V1 : Variable_Id := From.Attributes;
320 V2 : Variable_Id := No_Variable;
321 Var : Variable;
322 A1 : Array_Id := From.Arrays;
323 A2 : Array_Id := No_Array;
324 Arr : Array_Data;
325 E1 : Array_Element_Id;
326 E2 : Array_Element_Id := No_Array_Element;
327 Elm : Array_Element;
329 begin
330 -- To avoid references in error messages to attribute declarations in
331 -- an original package that has been renamed, copy all the attribute
332 -- declarations of the package and change all locations to New_Loc,
333 -- the location of the renamed package.
335 -- First single attributes
337 while V1 /= No_Variable loop
339 -- Copy the attribute
341 Var := In_Tree.Variable_Elements.Table (V1);
342 V1 := Var.Next;
344 -- Remove the Next component
346 Var.Next := No_Variable;
348 -- Change the location to New_Loc
350 Var.Value.Location := New_Loc;
351 Variable_Element_Table.Increment_Last (In_Tree.Variable_Elements);
353 -- Put in new declaration
355 if To.Attributes = No_Variable then
356 To.Attributes :=
357 Variable_Element_Table.Last (In_Tree.Variable_Elements);
359 else
360 In_Tree.Variable_Elements.Table (V2).Next :=
361 Variable_Element_Table.Last (In_Tree.Variable_Elements);
362 end if;
364 V2 := Variable_Element_Table.Last (In_Tree.Variable_Elements);
365 In_Tree.Variable_Elements.Table (V2) := Var;
366 end loop;
368 -- Then the associated array attributes
370 while A1 /= No_Array loop
372 -- Copy the array
374 Arr := In_Tree.Arrays.Table (A1);
375 A1 := Arr.Next;
377 -- Remove the Next component
379 Arr.Next := No_Array;
381 Array_Table.Increment_Last (In_Tree.Arrays);
383 -- Create new Array declaration
384 if To.Arrays = No_Array then
385 To.Arrays := Array_Table.Last (In_Tree.Arrays);
387 else
388 In_Tree.Arrays.Table (A2).Next :=
389 Array_Table.Last (In_Tree.Arrays);
390 end if;
392 A2 := Array_Table.Last (In_Tree.Arrays);
394 -- Don't store the array, as its first element has not been set yet
396 -- Copy the array elements of the array
398 E1 := Arr.Value;
399 Arr.Value := No_Array_Element;
401 while E1 /= No_Array_Element loop
403 -- Copy the array element
405 Elm := In_Tree.Array_Elements.Table (E1);
406 E1 := Elm.Next;
408 -- Remove the Next component
410 Elm.Next := No_Array_Element;
412 -- Change the location
414 Elm.Value.Location := New_Loc;
415 Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
417 -- Create new array element
419 if Arr.Value = No_Array_Element then
420 Arr.Value := Array_Element_Table.Last (In_Tree.Array_Elements);
421 else
422 In_Tree.Array_Elements.Table (E2).Next :=
423 Array_Element_Table.Last (In_Tree.Array_Elements);
424 end if;
426 E2 := Array_Element_Table.Last (In_Tree.Array_Elements);
427 In_Tree.Array_Elements.Table (E2) := Elm;
428 end loop;
430 -- Finally, store the new array
432 In_Tree.Arrays.Table (A2) := Arr;
433 end loop;
434 end Copy_Package_Declarations;
436 ----------------
437 -- Expression --
438 ----------------
440 function Expression
441 (Project : Project_Id;
442 In_Tree : Project_Tree_Ref;
443 From_Project_Node : Project_Node_Id;
444 From_Project_Node_Tree : Project_Node_Tree_Ref;
445 Pkg : Package_Id;
446 First_Term : Project_Node_Id;
447 Kind : Variable_Kind) return Variable_Value
449 The_Term : Project_Node_Id := First_Term;
450 -- The term in the expression list
452 The_Current_Term : Project_Node_Id := Empty_Node;
453 -- The current term node id
455 Result : Variable_Value (Kind => Kind);
456 -- The returned result
458 Last : String_List_Id := Nil_String;
459 -- Reference to the last string elements in Result, when Kind is List
461 begin
462 Result.Project := Project;
463 Result.Location := Location_Of (First_Term, From_Project_Node_Tree);
465 -- Process each term of the expression, starting with First_Term
467 while The_Term /= Empty_Node loop
468 The_Current_Term := Current_Term (The_Term, From_Project_Node_Tree);
470 case Kind_Of (The_Current_Term, From_Project_Node_Tree) is
472 when N_Literal_String =>
474 case Kind is
476 when Undefined =>
478 -- Should never happen
480 pragma Assert (False, "Undefined expression kind");
481 raise Program_Error;
483 when Single =>
484 Add (Result.Value,
485 String_Value_Of
486 (The_Current_Term, From_Project_Node_Tree));
487 Result.Index :=
488 Source_Index_Of
489 (The_Current_Term, From_Project_Node_Tree);
491 when List =>
493 String_Element_Table.Increment_Last
494 (In_Tree.String_Elements);
496 if Last = Nil_String then
498 -- This can happen in an expression like () & "toto"
500 Result.Values := String_Element_Table.Last
501 (In_Tree.String_Elements);
503 else
504 In_Tree.String_Elements.Table
505 (Last).Next := String_Element_Table.Last
506 (In_Tree.String_Elements);
507 end if;
509 Last := String_Element_Table.Last
510 (In_Tree.String_Elements);
511 In_Tree.String_Elements.Table (Last) :=
512 (Value =>
513 String_Value_Of
514 (The_Current_Term,
515 From_Project_Node_Tree),
516 Index =>
517 Source_Index_Of
518 (The_Current_Term, From_Project_Node_Tree),
519 Display_Value => No_Name,
520 Location =>
521 Location_Of
522 (The_Current_Term,
523 From_Project_Node_Tree),
524 Flag => False,
525 Next => Nil_String);
526 end case;
528 when N_Literal_String_List =>
530 declare
531 String_Node : Project_Node_Id :=
532 First_Expression_In_List
533 (The_Current_Term,
534 From_Project_Node_Tree);
536 Value : Variable_Value;
538 begin
539 if String_Node /= Empty_Node then
541 -- If String_Node is nil, it is an empty list,
542 -- there is nothing to do
544 Value := Expression
545 (Project => Project,
546 In_Tree => In_Tree,
547 From_Project_Node => From_Project_Node,
548 From_Project_Node_Tree => From_Project_Node_Tree,
549 Pkg => Pkg,
550 First_Term =>
551 Tree.First_Term
552 (String_Node, From_Project_Node_Tree),
553 Kind => Single);
554 String_Element_Table.Increment_Last
555 (In_Tree.String_Elements);
557 if Result.Values = Nil_String then
559 -- This literal string list is the first term
560 -- in a string list expression
562 Result.Values :=
563 String_Element_Table.Last (In_Tree.String_Elements);
565 else
566 In_Tree.String_Elements.Table
567 (Last).Next :=
568 String_Element_Table.Last (In_Tree.String_Elements);
569 end if;
571 Last :=
572 String_Element_Table.Last (In_Tree.String_Elements);
574 In_Tree.String_Elements.Table (Last) :=
575 (Value => Value.Value,
576 Display_Value => No_Name,
577 Location => Value.Location,
578 Flag => False,
579 Next => Nil_String,
580 Index => Value.Index);
582 loop
583 -- Add the other element of the literal string list
584 -- one after the other
586 String_Node :=
587 Next_Expression_In_List
588 (String_Node, From_Project_Node_Tree);
590 exit when String_Node = Empty_Node;
592 Value :=
593 Expression
594 (Project => Project,
595 In_Tree => In_Tree,
596 From_Project_Node => From_Project_Node,
597 From_Project_Node_Tree => From_Project_Node_Tree,
598 Pkg => Pkg,
599 First_Term =>
600 Tree.First_Term
601 (String_Node, From_Project_Node_Tree),
602 Kind => Single);
604 String_Element_Table.Increment_Last
605 (In_Tree.String_Elements);
606 In_Tree.String_Elements.Table
607 (Last).Next := String_Element_Table.Last
608 (In_Tree.String_Elements);
609 Last := String_Element_Table.Last
610 (In_Tree.String_Elements);
611 In_Tree.String_Elements.Table (Last) :=
612 (Value => Value.Value,
613 Display_Value => No_Name,
614 Location => Value.Location,
615 Flag => False,
616 Next => Nil_String,
617 Index => Value.Index);
618 end loop;
619 end if;
620 end;
622 when N_Variable_Reference | N_Attribute_Reference =>
624 declare
625 The_Project : Project_Id := Project;
626 The_Package : Package_Id := Pkg;
627 The_Name : Name_Id := No_Name;
628 The_Variable_Id : Variable_Id := No_Variable;
629 The_Variable : Variable_Value;
630 Term_Project : constant Project_Node_Id :=
631 Project_Node_Of
632 (The_Current_Term,
633 From_Project_Node_Tree);
634 Term_Package : constant Project_Node_Id :=
635 Package_Node_Of
636 (The_Current_Term,
637 From_Project_Node_Tree);
638 Index : Name_Id := No_Name;
640 begin
641 if Term_Project /= Empty_Node and then
642 Term_Project /= From_Project_Node
643 then
644 -- This variable or attribute comes from another project
646 The_Name :=
647 Name_Of (Term_Project, From_Project_Node_Tree);
648 The_Project := Imported_Or_Extended_Project_From
649 (Project => Project,
650 In_Tree => In_Tree,
651 With_Name => The_Name);
652 end if;
654 if Term_Package /= Empty_Node then
656 -- This is an attribute of a package
658 The_Name :=
659 Name_Of (Term_Package, From_Project_Node_Tree);
660 The_Package := In_Tree.Projects.Table
661 (The_Project).Decl.Packages;
663 while The_Package /= No_Package
664 and then In_Tree.Packages.Table
665 (The_Package).Name /= The_Name
666 loop
667 The_Package :=
668 In_Tree.Packages.Table
669 (The_Package).Next;
670 end loop;
672 pragma Assert
673 (The_Package /= No_Package,
674 "package not found.");
676 elsif Kind_Of (The_Current_Term, From_Project_Node_Tree) =
677 N_Attribute_Reference
678 then
679 The_Package := No_Package;
680 end if;
682 The_Name :=
683 Name_Of (The_Current_Term, From_Project_Node_Tree);
685 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
686 N_Attribute_Reference
687 then
688 Index :=
689 Associative_Array_Index_Of
690 (The_Current_Term, From_Project_Node_Tree);
691 end if;
693 -- If it is not an associative array attribute
695 if Index = No_Name then
697 -- It is not an associative array attribute
699 if The_Package /= No_Package then
701 -- First, if there is a package, look into the package
703 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
704 N_Variable_Reference
705 then
706 The_Variable_Id :=
707 In_Tree.Packages.Table
708 (The_Package).Decl.Variables;
709 else
710 The_Variable_Id :=
711 In_Tree.Packages.Table
712 (The_Package).Decl.Attributes;
713 end if;
715 while The_Variable_Id /= No_Variable
716 and then
717 In_Tree.Variable_Elements.Table
718 (The_Variable_Id).Name /= The_Name
719 loop
720 The_Variable_Id :=
721 In_Tree.Variable_Elements.Table
722 (The_Variable_Id).Next;
723 end loop;
725 end if;
727 if The_Variable_Id = No_Variable then
729 -- If we have not found it, look into the project
731 if Kind_Of (The_Current_Term, From_Project_Node_Tree) =
732 N_Variable_Reference
733 then
734 The_Variable_Id :=
735 In_Tree.Projects.Table
736 (The_Project).Decl.Variables;
737 else
738 The_Variable_Id :=
739 In_Tree.Projects.Table
740 (The_Project).Decl.Attributes;
741 end if;
743 while The_Variable_Id /= No_Variable
744 and then
745 In_Tree.Variable_Elements.Table
746 (The_Variable_Id).Name /= The_Name
747 loop
748 The_Variable_Id :=
749 In_Tree.Variable_Elements.Table
750 (The_Variable_Id).Next;
751 end loop;
753 end if;
755 pragma Assert (The_Variable_Id /= No_Variable,
756 "variable or attribute not found");
758 The_Variable :=
759 In_Tree.Variable_Elements.Table
760 (The_Variable_Id).Value;
762 else
764 -- It is an associative array attribute
766 declare
767 The_Array : Array_Id := No_Array;
768 The_Element : Array_Element_Id := No_Array_Element;
769 Array_Index : Name_Id := No_Name;
770 Lower : Boolean;
772 begin
773 if The_Package /= No_Package then
774 The_Array :=
775 In_Tree.Packages.Table
776 (The_Package).Decl.Arrays;
777 else
778 The_Array :=
779 In_Tree.Projects.Table
780 (The_Project).Decl.Arrays;
781 end if;
783 while The_Array /= No_Array
784 and then In_Tree.Arrays.Table
785 (The_Array).Name /= The_Name
786 loop
787 The_Array := In_Tree.Arrays.Table
788 (The_Array).Next;
789 end loop;
791 if The_Array /= No_Array then
792 The_Element := In_Tree.Arrays.Table
793 (The_Array).Value;
795 Get_Name_String (Index);
797 Lower :=
798 Case_Insensitive
799 (The_Current_Term, From_Project_Node_Tree);
801 -- In multi-language mode (gprbuild), the index is
802 -- always case insensitive if it does not include
803 -- any dot.
805 if Get_Mode = Multi_Language and then not Lower then
806 Lower := True;
808 for J in 1 .. Name_Len loop
809 if Name_Buffer (J) = '.' then
810 Lower := False;
811 exit;
812 end if;
813 end loop;
814 end if;
816 if Lower then
817 To_Lower (Name_Buffer (1 .. Name_Len));
818 end if;
820 Array_Index := Name_Find;
822 while The_Element /= No_Array_Element
823 and then
824 In_Tree.Array_Elements.Table
825 (The_Element).Index /= Array_Index
826 loop
827 The_Element :=
828 In_Tree.Array_Elements.Table
829 (The_Element).Next;
830 end loop;
832 end if;
834 if The_Element /= No_Array_Element then
835 The_Variable :=
836 In_Tree.Array_Elements.Table
837 (The_Element).Value;
839 else
840 if Expression_Kind_Of
841 (The_Current_Term, From_Project_Node_Tree) =
842 List
843 then
844 The_Variable :=
845 (Project => Project,
846 Kind => List,
847 Location => No_Location,
848 Default => True,
849 Values => Nil_String);
850 else
851 The_Variable :=
852 (Project => Project,
853 Kind => Single,
854 Location => No_Location,
855 Default => True,
856 Value => Empty_String,
857 Index => 0);
858 end if;
859 end if;
860 end;
861 end if;
863 case Kind is
865 when Undefined =>
867 -- Should never happen
869 pragma Assert (False, "undefined expression kind");
870 null;
872 when Single =>
874 case The_Variable.Kind is
876 when Undefined =>
877 null;
879 when Single =>
880 Add (Result.Value, The_Variable.Value);
882 when List =>
884 -- Should never happen
886 pragma Assert
887 (False,
888 "list cannot appear in single " &
889 "string expression");
890 null;
891 end case;
893 when List =>
894 case The_Variable.Kind is
896 when Undefined =>
897 null;
899 when Single =>
900 String_Element_Table.Increment_Last
901 (In_Tree.String_Elements);
903 if Last = Nil_String then
905 -- This can happen in an expression such as
906 -- () & Var
908 Result.Values :=
909 String_Element_Table.Last
910 (In_Tree.String_Elements);
912 else
913 In_Tree.String_Elements.Table
914 (Last).Next :=
915 String_Element_Table.Last
916 (In_Tree.String_Elements);
917 end if;
919 Last :=
920 String_Element_Table.Last
921 (In_Tree.String_Elements);
923 In_Tree.String_Elements.Table (Last) :=
924 (Value => The_Variable.Value,
925 Display_Value => No_Name,
926 Location => Location_Of
927 (The_Current_Term,
928 From_Project_Node_Tree),
929 Flag => False,
930 Next => Nil_String,
931 Index => 0);
933 when List =>
935 declare
936 The_List : String_List_Id :=
937 The_Variable.Values;
939 begin
940 while The_List /= Nil_String loop
941 String_Element_Table.Increment_Last
942 (In_Tree.String_Elements);
944 if Last = Nil_String then
945 Result.Values :=
946 String_Element_Table.Last
947 (In_Tree.
948 String_Elements);
950 else
951 In_Tree.
952 String_Elements.Table (Last).Next :=
953 String_Element_Table.Last
954 (In_Tree.
955 String_Elements);
957 end if;
959 Last :=
960 String_Element_Table.Last
961 (In_Tree.String_Elements);
963 In_Tree.String_Elements.Table (Last) :=
964 (Value =>
965 In_Tree.String_Elements.Table
966 (The_List).Value,
967 Display_Value => No_Name,
968 Location =>
969 Location_Of
970 (The_Current_Term,
971 From_Project_Node_Tree),
972 Flag => False,
973 Next => Nil_String,
974 Index => 0);
976 The_List :=
977 In_Tree. String_Elements.Table
978 (The_List).Next;
979 end loop;
980 end;
981 end case;
982 end case;
983 end;
985 when N_External_Value =>
986 Get_Name_String
987 (String_Value_Of
988 (External_Reference_Of
989 (The_Current_Term, From_Project_Node_Tree),
990 From_Project_Node_Tree));
992 declare
993 Name : constant Name_Id := Name_Find;
994 Default : Name_Id := No_Name;
995 Value : Name_Id := No_Name;
997 Def_Var : Variable_Value;
999 Default_Node : constant Project_Node_Id :=
1000 External_Default_Of
1001 (The_Current_Term, From_Project_Node_Tree);
1003 begin
1004 -- If there is a default value for the external reference,
1005 -- get its value.
1007 if Default_Node /= Empty_Node then
1008 Def_Var := Expression
1009 (Project => Project,
1010 In_Tree => In_Tree,
1011 From_Project_Node => Default_Node,
1012 From_Project_Node_Tree => From_Project_Node_Tree,
1013 Pkg => Pkg,
1014 First_Term =>
1015 Tree.First_Term
1016 (Default_Node, From_Project_Node_Tree),
1017 Kind => Single);
1019 if Def_Var /= Nil_Variable_Value then
1020 Default := Def_Var.Value;
1021 end if;
1022 end if;
1024 Value := Prj.Ext.Value_Of (Name, Default);
1026 if Value = No_Name then
1027 if not Quiet_Output then
1028 if Error_Report = null then
1029 Error_Msg
1030 ("?undefined external reference",
1031 Location_Of
1032 (The_Current_Term, From_Project_Node_Tree));
1033 else
1034 Error_Report
1035 ("warning: """ & Get_Name_String (Name) &
1036 """ is an undefined external reference",
1037 Project, In_Tree);
1038 end if;
1039 end if;
1041 Value := Empty_String;
1042 end if;
1044 case Kind is
1046 when Undefined =>
1047 null;
1049 when Single =>
1050 Add (Result.Value, Value);
1052 when List =>
1053 String_Element_Table.Increment_Last
1054 (In_Tree.String_Elements);
1056 if Last = Nil_String then
1057 Result.Values := String_Element_Table.Last
1058 (In_Tree.String_Elements);
1060 else
1061 In_Tree.String_Elements.Table
1062 (Last).Next := String_Element_Table.Last
1063 (In_Tree.String_Elements);
1064 end if;
1066 Last := String_Element_Table.Last
1067 (In_Tree.String_Elements);
1068 In_Tree.String_Elements.Table (Last) :=
1069 (Value => Value,
1070 Display_Value => No_Name,
1071 Location =>
1072 Location_Of
1073 (The_Current_Term, From_Project_Node_Tree),
1074 Flag => False,
1075 Next => Nil_String,
1076 Index => 0);
1078 end case;
1079 end;
1081 when others =>
1083 -- Should never happen
1085 pragma Assert
1086 (False,
1087 "illegal node kind in an expression");
1088 raise Program_Error;
1090 end case;
1092 The_Term := Next_Term (The_Term, From_Project_Node_Tree);
1093 end loop;
1095 return Result;
1096 end Expression;
1098 ---------------------------------------
1099 -- Imported_Or_Extended_Project_From --
1100 ---------------------------------------
1102 function Imported_Or_Extended_Project_From
1103 (Project : Project_Id;
1104 In_Tree : Project_Tree_Ref;
1105 With_Name : Name_Id) return Project_Id
1107 Data : constant Project_Data :=
1108 In_Tree.Projects.Table (Project);
1109 List : Project_List := Data.Imported_Projects;
1110 Result : Project_Id := No_Project;
1111 Temp_Result : Project_Id := No_Project;
1113 begin
1114 -- First check if it is the name of an extended project
1116 if Data.Extends /= No_Project
1117 and then In_Tree.Projects.Table (Data.Extends).Name =
1118 With_Name
1119 then
1120 return Data.Extends;
1122 else
1123 -- Then check the name of each imported project
1125 while List /= Empty_Project_List loop
1126 Result := In_Tree.Project_Lists.Table (List).Project;
1128 -- If the project is directly imported, then returns its ID
1131 In_Tree.Projects.Table (Result).Name = With_Name
1132 then
1133 return Result;
1134 end if;
1136 -- If a project extending the project is imported, then keep
1137 -- this extending project as a possibility. It will be the
1138 -- returned ID if the project is not imported directly.
1140 declare
1141 Proj : Project_Id :=
1142 In_Tree.Projects.Table (Result).Extends;
1143 begin
1144 while Proj /= No_Project loop
1145 if In_Tree.Projects.Table (Proj).Name =
1146 With_Name
1147 then
1148 Temp_Result := Result;
1149 exit;
1150 end if;
1152 Proj := In_Tree.Projects.Table (Proj).Extends;
1153 end loop;
1154 end;
1156 List := In_Tree.Project_Lists.Table (List).Next;
1157 end loop;
1159 pragma Assert
1160 (Temp_Result /= No_Project,
1161 "project not found");
1163 return Temp_Result;
1164 end if;
1165 end Imported_Or_Extended_Project_From;
1167 ------------------
1168 -- Package_From --
1169 ------------------
1171 function Package_From
1172 (Project : Project_Id;
1173 In_Tree : Project_Tree_Ref;
1174 With_Name : Name_Id) return Package_Id
1176 Data : constant Project_Data :=
1177 In_Tree.Projects.Table (Project);
1178 Result : Package_Id := Data.Decl.Packages;
1180 begin
1181 -- Check the name of each existing package of Project
1183 while Result /= No_Package
1184 and then In_Tree.Packages.Table (Result).Name /= With_Name
1185 loop
1186 Result := In_Tree.Packages.Table (Result).Next;
1187 end loop;
1189 if Result = No_Package then
1191 -- Should never happen
1193 Write_Line ("package """ & Get_Name_String (With_Name) &
1194 """ not found");
1195 raise Program_Error;
1197 else
1198 return Result;
1199 end if;
1200 end Package_From;
1202 -------------
1203 -- Process --
1204 -------------
1206 procedure Process
1207 (In_Tree : Project_Tree_Ref;
1208 Project : out Project_Id;
1209 Success : out Boolean;
1210 From_Project_Node : Project_Node_Id;
1211 From_Project_Node_Tree : Project_Node_Tree_Ref;
1212 Report_Error : Put_Line_Access;
1213 When_No_Sources : Error_Warning := Error;
1214 Reset_Tree : Boolean := True;
1215 Current_Dir : String := "")
1217 begin
1218 Process_Project_Tree_Phase_1
1219 (In_Tree => In_Tree,
1220 Project => Project,
1221 Success => Success,
1222 From_Project_Node => From_Project_Node,
1223 From_Project_Node_Tree => From_Project_Node_Tree,
1224 Report_Error => Report_Error,
1225 Reset_Tree => Reset_Tree);
1227 if not In_Configuration then
1228 Process_Project_Tree_Phase_2
1229 (In_Tree => In_Tree,
1230 Project => Project,
1231 Success => Success,
1232 From_Project_Node => From_Project_Node,
1233 From_Project_Node_Tree => From_Project_Node_Tree,
1234 Report_Error => Report_Error,
1235 When_No_Sources => When_No_Sources,
1236 Current_Dir => Current_Dir);
1237 end if;
1238 end Process;
1240 -------------------------------
1241 -- Process_Declarative_Items --
1242 -------------------------------
1244 procedure Process_Declarative_Items
1245 (Project : Project_Id;
1246 In_Tree : Project_Tree_Ref;
1247 From_Project_Node : Project_Node_Id;
1248 From_Project_Node_Tree : Project_Node_Tree_Ref;
1249 Pkg : Package_Id;
1250 Item : Project_Node_Id)
1252 Current_Declarative_Item : Project_Node_Id;
1253 Current_Item : Project_Node_Id;
1255 begin
1256 -- Loop through declarative items
1258 Current_Item := Empty_Node;
1260 Current_Declarative_Item := Item;
1261 while Current_Declarative_Item /= Empty_Node loop
1263 -- Get its data
1265 Current_Item :=
1266 Current_Item_Node
1267 (Current_Declarative_Item, From_Project_Node_Tree);
1269 -- And set Current_Declarative_Item to the next declarative item
1270 -- ready for the next iteration.
1272 Current_Declarative_Item :=
1273 Next_Declarative_Item
1274 (Current_Declarative_Item, From_Project_Node_Tree);
1276 case Kind_Of (Current_Item, From_Project_Node_Tree) is
1278 when N_Package_Declaration =>
1280 -- Do not process a package declaration that should be ignored
1282 if Expression_Kind_Of
1283 (Current_Item, From_Project_Node_Tree) /= Ignored
1284 then
1285 -- Create the new package
1287 Package_Table.Increment_Last (In_Tree.Packages);
1289 declare
1290 New_Pkg : constant Package_Id :=
1291 Package_Table.Last (In_Tree.Packages);
1292 The_New_Package : Package_Element;
1294 Project_Of_Renamed_Package :
1295 constant Project_Node_Id :=
1296 Project_Of_Renamed_Package_Of
1297 (Current_Item, From_Project_Node_Tree);
1299 begin
1300 -- Set the name of the new package
1302 The_New_Package.Name :=
1303 Name_Of (Current_Item, From_Project_Node_Tree);
1305 -- Insert the new package in the appropriate list
1307 if Pkg /= No_Package then
1308 The_New_Package.Next :=
1309 In_Tree.Packages.Table (Pkg).Decl.Packages;
1310 In_Tree.Packages.Table (Pkg).Decl.Packages :=
1311 New_Pkg;
1313 else
1314 The_New_Package.Next :=
1315 In_Tree.Projects.Table (Project).Decl.Packages;
1316 In_Tree.Projects.Table (Project).Decl.Packages :=
1317 New_Pkg;
1318 end if;
1320 In_Tree.Packages.Table (New_Pkg) :=
1321 The_New_Package;
1323 if Project_Of_Renamed_Package /= Empty_Node then
1325 -- Renamed package
1327 declare
1328 Project_Name : constant Name_Id :=
1329 Name_Of
1330 (Project_Of_Renamed_Package,
1331 From_Project_Node_Tree);
1333 Renamed_Project :
1334 constant Project_Id :=
1335 Imported_Or_Extended_Project_From
1336 (Project, In_Tree, Project_Name);
1338 Renamed_Package : constant Package_Id :=
1339 Package_From
1340 (Renamed_Project, In_Tree,
1341 Name_Of
1342 (Current_Item,
1343 From_Project_Node_Tree));
1345 begin
1346 -- For a renamed package, copy the declarations of
1347 -- the renamed package, but set all the locations
1348 -- to the location of the package name in the
1349 -- renaming declaration.
1351 Copy_Package_Declarations
1352 (From =>
1353 In_Tree.Packages.Table (Renamed_Package).Decl,
1354 To =>
1355 In_Tree.Packages.Table (New_Pkg).Decl,
1356 New_Loc =>
1357 Location_Of
1358 (Current_Item, From_Project_Node_Tree),
1359 In_Tree => In_Tree);
1360 end;
1362 -- Standard package declaration, not renaming
1364 else
1365 -- Set the default values of the attributes
1367 Add_Attributes
1368 (Project,
1369 In_Tree.Projects.Table (Project).Name,
1370 In_Tree,
1371 In_Tree.Packages.Table (New_Pkg).Decl,
1372 First_Attribute_Of
1373 (Package_Id_Of
1374 (Current_Item, From_Project_Node_Tree)),
1375 Project_Level => False);
1377 -- And process declarative items of the new package
1379 Process_Declarative_Items
1380 (Project => Project,
1381 In_Tree => In_Tree,
1382 From_Project_Node => From_Project_Node,
1383 From_Project_Node_Tree => From_Project_Node_Tree,
1384 Pkg => New_Pkg,
1385 Item =>
1386 First_Declarative_Item_Of
1387 (Current_Item, From_Project_Node_Tree));
1388 end if;
1389 end;
1390 end if;
1392 when N_String_Type_Declaration =>
1394 -- There is nothing to process
1396 null;
1398 when N_Attribute_Declaration |
1399 N_Typed_Variable_Declaration |
1400 N_Variable_Declaration =>
1402 if Expression_Of (Current_Item, From_Project_Node_Tree) =
1403 Empty_Node
1404 then
1406 -- It must be a full associative array attribute declaration
1408 declare
1409 Current_Item_Name : constant Name_Id :=
1410 Name_Of
1411 (Current_Item,
1412 From_Project_Node_Tree);
1413 -- The name of the attribute
1415 New_Array : Array_Id;
1416 -- The new associative array created
1418 Orig_Array : Array_Id;
1419 -- The associative array value
1421 Orig_Project_Name : Name_Id := No_Name;
1422 -- The name of the project where the associative array
1423 -- value is.
1425 Orig_Project : Project_Id := No_Project;
1426 -- The id of the project where the associative array
1427 -- value is.
1429 Orig_Package_Name : Name_Id := No_Name;
1430 -- The name of the package, if any, where the associative
1431 -- array value is.
1433 Orig_Package : Package_Id := No_Package;
1434 -- The id of the package, if any, where the associative
1435 -- array value is.
1437 New_Element : Array_Element_Id := No_Array_Element;
1438 -- Id of a new array element created
1440 Prev_Element : Array_Element_Id := No_Array_Element;
1441 -- Last new element id created
1443 Orig_Element : Array_Element_Id := No_Array_Element;
1444 -- Current array element in original associative array
1446 Next_Element : Array_Element_Id := No_Array_Element;
1447 -- Id of the array element that follows the new element.
1448 -- This is not always nil, because values for the
1449 -- associative array attribute may already have been
1450 -- declared, and the array elements declared are reused.
1452 begin
1453 -- First find if the associative array attribute already
1454 -- has elements declared.
1456 if Pkg /= No_Package then
1457 New_Array := In_Tree.Packages.Table
1458 (Pkg).Decl.Arrays;
1460 else
1461 New_Array := In_Tree.Projects.Table
1462 (Project).Decl.Arrays;
1463 end if;
1465 while New_Array /= No_Array
1466 and then In_Tree.Arrays.Table (New_Array).Name /=
1467 Current_Item_Name
1468 loop
1469 New_Array := In_Tree.Arrays.Table (New_Array).Next;
1470 end loop;
1472 -- If the attribute has never been declared add new entry
1473 -- in the arrays of the project/package and link it.
1475 if New_Array = No_Array then
1476 Array_Table.Increment_Last (In_Tree.Arrays);
1477 New_Array := Array_Table.Last (In_Tree.Arrays);
1479 if Pkg /= No_Package then
1480 In_Tree.Arrays.Table (New_Array) :=
1481 (Name => Current_Item_Name,
1482 Value => No_Array_Element,
1483 Next =>
1484 In_Tree.Packages.Table (Pkg).Decl.Arrays);
1486 In_Tree.Packages.Table (Pkg).Decl.Arrays :=
1487 New_Array;
1489 else
1490 In_Tree.Arrays.Table (New_Array) :=
1491 (Name => Current_Item_Name,
1492 Value => No_Array_Element,
1493 Next =>
1494 In_Tree.Projects.Table (Project).Decl.Arrays);
1496 In_Tree.Projects.Table (Project).Decl.Arrays :=
1497 New_Array;
1498 end if;
1499 end if;
1501 -- Find the project where the value is declared
1503 Orig_Project_Name :=
1504 Name_Of
1505 (Associative_Project_Of
1506 (Current_Item, From_Project_Node_Tree),
1507 From_Project_Node_Tree);
1509 for Index in Project_Table.First ..
1510 Project_Table.Last
1511 (In_Tree.Projects)
1512 loop
1513 if In_Tree.Projects.Table (Index).Name =
1514 Orig_Project_Name
1515 then
1516 Orig_Project := Index;
1517 exit;
1518 end if;
1519 end loop;
1521 pragma Assert (Orig_Project /= No_Project,
1522 "original project not found");
1524 if Associative_Package_Of
1525 (Current_Item, From_Project_Node_Tree) = Empty_Node
1526 then
1527 Orig_Array :=
1528 In_Tree.Projects.Table
1529 (Orig_Project).Decl.Arrays;
1531 else
1532 -- If in a package, find the package where the value
1533 -- is declared.
1535 Orig_Package_Name :=
1536 Name_Of
1537 (Associative_Package_Of
1538 (Current_Item, From_Project_Node_Tree),
1539 From_Project_Node_Tree);
1541 Orig_Package :=
1542 In_Tree.Projects.Table
1543 (Orig_Project).Decl.Packages;
1544 pragma Assert (Orig_Package /= No_Package,
1545 "original package not found");
1547 while In_Tree.Packages.Table
1548 (Orig_Package).Name /= Orig_Package_Name
1549 loop
1550 Orig_Package := In_Tree.Packages.Table
1551 (Orig_Package).Next;
1552 pragma Assert (Orig_Package /= No_Package,
1553 "original package not found");
1554 end loop;
1556 Orig_Array :=
1557 In_Tree.Packages.Table
1558 (Orig_Package).Decl.Arrays;
1559 end if;
1561 -- Now look for the array
1563 while Orig_Array /= No_Array
1564 and then In_Tree.Arrays.Table (Orig_Array).Name /=
1565 Current_Item_Name
1566 loop
1567 Orig_Array := In_Tree.Arrays.Table
1568 (Orig_Array).Next;
1569 end loop;
1571 if Orig_Array = No_Array then
1572 if Error_Report = null then
1573 Error_Msg
1574 ("associative array value cannot be found",
1575 Location_Of
1576 (Current_Item, From_Project_Node_Tree));
1577 else
1578 Error_Report
1579 ("associative array value cannot be found",
1580 Project, In_Tree);
1581 end if;
1583 else
1584 Orig_Element :=
1585 In_Tree.Arrays.Table (Orig_Array).Value;
1587 -- Copy each array element
1589 while Orig_Element /= No_Array_Element loop
1591 -- Case of first element
1593 if Prev_Element = No_Array_Element then
1595 -- And there is no array element declared yet,
1596 -- create a new first array element.
1598 if In_Tree.Arrays.Table (New_Array).Value =
1599 No_Array_Element
1600 then
1601 Array_Element_Table.Increment_Last
1602 (In_Tree.Array_Elements);
1603 New_Element := Array_Element_Table.Last
1604 (In_Tree.Array_Elements);
1605 In_Tree.Arrays.Table
1606 (New_Array).Value := New_Element;
1607 Next_Element := No_Array_Element;
1609 -- Otherwise, the new element is the first
1611 else
1612 New_Element := In_Tree.Arrays.
1613 Table (New_Array).Value;
1614 Next_Element :=
1615 In_Tree.Array_Elements.Table
1616 (New_Element).Next;
1617 end if;
1619 -- Otherwise, reuse an existing element, or create
1620 -- one if necessary.
1622 else
1623 Next_Element :=
1624 In_Tree.Array_Elements.Table
1625 (Prev_Element).Next;
1627 if Next_Element = No_Array_Element then
1628 Array_Element_Table.Increment_Last
1629 (In_Tree.Array_Elements);
1630 New_Element := Array_Element_Table.Last
1631 (In_Tree.Array_Elements);
1633 else
1634 New_Element := Next_Element;
1635 Next_Element :=
1636 In_Tree.Array_Elements.Table
1637 (New_Element).Next;
1638 end if;
1639 end if;
1641 -- Copy the value of the element
1643 In_Tree.Array_Elements.Table
1644 (New_Element) :=
1645 In_Tree.Array_Elements.Table
1646 (Orig_Element);
1647 In_Tree.Array_Elements.Table
1648 (New_Element).Value.Project := Project;
1650 -- Adjust the Next link
1652 In_Tree.Array_Elements.Table
1653 (New_Element).Next := Next_Element;
1655 -- Adjust the previous id for the next element
1657 Prev_Element := New_Element;
1659 -- Go to the next element in the original array
1661 Orig_Element :=
1662 In_Tree.Array_Elements.Table
1663 (Orig_Element).Next;
1664 end loop;
1666 -- Make sure that the array ends here, in case there
1667 -- previously a greater number of elements.
1669 In_Tree.Array_Elements.Table
1670 (New_Element).Next := No_Array_Element;
1671 end if;
1672 end;
1674 -- Declarations other that full associative arrays
1676 else
1677 declare
1678 New_Value : constant Variable_Value :=
1679 Expression
1680 (Project => Project,
1681 In_Tree => In_Tree,
1682 From_Project_Node => From_Project_Node,
1683 From_Project_Node_Tree => From_Project_Node_Tree,
1684 Pkg => Pkg,
1685 First_Term =>
1686 Tree.First_Term
1687 (Expression_Of
1688 (Current_Item, From_Project_Node_Tree),
1689 From_Project_Node_Tree),
1690 Kind =>
1691 Expression_Kind_Of
1692 (Current_Item, From_Project_Node_Tree));
1693 -- The expression value
1695 The_Variable : Variable_Id := No_Variable;
1697 Current_Item_Name : constant Name_Id :=
1698 Name_Of
1699 (Current_Item,
1700 From_Project_Node_Tree);
1702 begin
1703 -- Process a typed variable declaration
1705 if Kind_Of (Current_Item, From_Project_Node_Tree) =
1706 N_Typed_Variable_Declaration
1707 then
1708 -- Report an error for an empty string
1710 if New_Value.Value = Empty_String then
1711 Error_Msg_Name_1 :=
1712 Name_Of (Current_Item, From_Project_Node_Tree);
1714 if Error_Report = null then
1715 Error_Msg
1716 ("no value defined for %%",
1717 Location_Of
1718 (Current_Item, From_Project_Node_Tree));
1719 else
1720 Error_Report
1721 ("no value defined for " &
1722 Get_Name_String (Error_Msg_Name_1),
1723 Project, In_Tree);
1724 end if;
1726 else
1727 declare
1728 Current_String : Project_Node_Id;
1730 begin
1731 -- Loop through all the valid strings for the
1732 -- string type and compare to the string value.
1734 Current_String :=
1735 First_Literal_String
1736 (String_Type_Of (Current_Item,
1737 From_Project_Node_Tree),
1738 From_Project_Node_Tree);
1739 while Current_String /= Empty_Node
1740 and then
1741 String_Value_Of
1742 (Current_String, From_Project_Node_Tree) /=
1743 New_Value.Value
1744 loop
1745 Current_String :=
1746 Next_Literal_String
1747 (Current_String, From_Project_Node_Tree);
1748 end loop;
1750 -- Report an error if the string value is not
1751 -- one for the string type.
1753 if Current_String = Empty_Node then
1754 Error_Msg_Name_1 := New_Value.Value;
1755 Error_Msg_Name_2 :=
1756 Name_Of
1757 (Current_Item, From_Project_Node_Tree);
1759 if Error_Report = null then
1760 Error_Msg
1761 ("value %% is illegal " &
1762 "for typed string %%",
1763 Location_Of
1764 (Current_Item,
1765 From_Project_Node_Tree));
1767 else
1768 Error_Report
1769 ("value """ &
1770 Get_Name_String (Error_Msg_Name_1) &
1771 """ is illegal for typed string """ &
1772 Get_Name_String (Error_Msg_Name_2) &
1773 """",
1774 Project, In_Tree);
1775 end if;
1776 end if;
1777 end;
1778 end if;
1779 end if;
1781 -- Comment here ???
1783 if Kind_Of (Current_Item, From_Project_Node_Tree) /=
1784 N_Attribute_Declaration
1785 or else
1786 Associative_Array_Index_Of
1787 (Current_Item, From_Project_Node_Tree) = No_Name
1788 then
1789 -- Case of a variable declaration or of a not
1790 -- associative array attribute.
1792 -- First, find the list where to find the variable
1793 -- or attribute.
1795 if Kind_Of (Current_Item, From_Project_Node_Tree) =
1796 N_Attribute_Declaration
1797 then
1798 if Pkg /= No_Package then
1799 The_Variable :=
1800 In_Tree.Packages.Table
1801 (Pkg).Decl.Attributes;
1802 else
1803 The_Variable :=
1804 In_Tree.Projects.Table
1805 (Project).Decl.Attributes;
1806 end if;
1808 else
1809 if Pkg /= No_Package then
1810 The_Variable :=
1811 In_Tree.Packages.Table
1812 (Pkg).Decl.Variables;
1813 else
1814 The_Variable :=
1815 In_Tree.Projects.Table
1816 (Project).Decl.Variables;
1817 end if;
1819 end if;
1821 -- Loop through the list, to find if it has already
1822 -- been declared.
1824 while The_Variable /= No_Variable
1825 and then
1826 In_Tree.Variable_Elements.Table
1827 (The_Variable).Name /= Current_Item_Name
1828 loop
1829 The_Variable :=
1830 In_Tree.Variable_Elements.Table
1831 (The_Variable).Next;
1832 end loop;
1834 -- If it has not been declared, create a new entry
1835 -- in the list.
1837 if The_Variable = No_Variable then
1839 -- All single string attribute should already have
1840 -- been declared with a default empty string value.
1842 pragma Assert
1843 (Kind_Of (Current_Item, From_Project_Node_Tree) /=
1844 N_Attribute_Declaration,
1845 "illegal attribute declaration");
1847 Variable_Element_Table.Increment_Last
1848 (In_Tree.Variable_Elements);
1849 The_Variable := Variable_Element_Table.Last
1850 (In_Tree.Variable_Elements);
1852 -- Put the new variable in the appropriate list
1854 if Pkg /= No_Package then
1855 In_Tree.Variable_Elements.Table (The_Variable) :=
1856 (Next =>
1857 In_Tree.Packages.Table
1858 (Pkg).Decl.Variables,
1859 Name => Current_Item_Name,
1860 Value => New_Value);
1861 In_Tree.Packages.Table
1862 (Pkg).Decl.Variables := The_Variable;
1864 else
1865 In_Tree.Variable_Elements.Table (The_Variable) :=
1866 (Next =>
1867 In_Tree.Projects.Table
1868 (Project).Decl.Variables,
1869 Name => Current_Item_Name,
1870 Value => New_Value);
1871 In_Tree.Projects.Table
1872 (Project).Decl.Variables :=
1873 The_Variable;
1874 end if;
1876 -- If the variable/attribute has already been
1877 -- declared, just change the value.
1879 else
1880 In_Tree.Variable_Elements.Table
1881 (The_Variable).Value :=
1882 New_Value;
1884 end if;
1886 -- Associative array attribute
1888 else
1889 -- Get the string index
1891 Get_Name_String
1892 (Associative_Array_Index_Of
1893 (Current_Item, From_Project_Node_Tree));
1895 -- Put in lower case, if necessary
1897 declare
1898 Lower : Boolean;
1900 begin
1901 Lower :=
1902 Case_Insensitive
1903 (Current_Item, From_Project_Node_Tree);
1905 -- In multi-language mode (gprbuild), the index is
1906 -- always case insensitive if it does not include
1907 -- any dot.
1909 if Get_Mode = Multi_Language and then not Lower then
1910 for J in 1 .. Name_Len loop
1911 if Name_Buffer (J) = '.' then
1912 Lower := False;
1913 exit;
1914 end if;
1915 end loop;
1916 end if;
1918 if Lower then
1919 GNAT.Case_Util.To_Lower
1920 (Name_Buffer (1 .. Name_Len));
1921 end if;
1922 end;
1924 declare
1925 The_Array : Array_Id;
1927 The_Array_Element : Array_Element_Id :=
1928 No_Array_Element;
1930 Index_Name : constant Name_Id := Name_Find;
1931 -- The name id of the index
1933 begin
1934 -- Look for the array in the appropriate list
1936 if Pkg /= No_Package then
1937 The_Array :=
1938 In_Tree.Packages.Table (Pkg).Decl.Arrays;
1940 else
1941 The_Array :=
1942 In_Tree.Projects.Table (Project).Decl.Arrays;
1943 end if;
1945 while
1946 The_Array /= No_Array
1947 and then
1948 In_Tree.Arrays.Table (The_Array).Name /=
1949 Current_Item_Name
1950 loop
1951 The_Array := In_Tree.Arrays.Table
1952 (The_Array).Next;
1953 end loop;
1955 -- If the array cannot be found, create a new entry
1956 -- in the list. As The_Array_Element is initialized
1957 -- to No_Array_Element, a new element will be
1958 -- created automatically later
1960 if The_Array = No_Array then
1961 Array_Table.Increment_Last (In_Tree.Arrays);
1962 The_Array := Array_Table.Last (In_Tree.Arrays);
1964 if Pkg /= No_Package then
1965 In_Tree.Arrays.Table (The_Array) :=
1966 (Name => Current_Item_Name,
1967 Value => No_Array_Element,
1968 Next =>
1969 In_Tree.Packages.Table
1970 (Pkg).Decl.Arrays);
1972 In_Tree.Packages.Table (Pkg).Decl.Arrays :=
1973 The_Array;
1975 else
1976 In_Tree.Arrays.Table (The_Array) :=
1977 (Name => Current_Item_Name,
1978 Value => No_Array_Element,
1979 Next =>
1980 In_Tree.Projects.Table
1981 (Project).Decl.Arrays);
1983 In_Tree.Projects.Table
1984 (Project).Decl.Arrays := The_Array;
1985 end if;
1987 -- Otherwise initialize The_Array_Element as the
1988 -- head of the element list.
1990 else
1991 The_Array_Element :=
1992 In_Tree.Arrays.Table (The_Array).Value;
1993 end if;
1995 -- Look in the list, if any, to find an element
1996 -- with the same index.
1998 while The_Array_Element /= No_Array_Element
1999 and then
2000 In_Tree.Array_Elements.Table
2001 (The_Array_Element).Index /= Index_Name
2002 loop
2003 The_Array_Element :=
2004 In_Tree.Array_Elements.Table
2005 (The_Array_Element).Next;
2006 end loop;
2008 -- If no such element were found, create a new one
2009 -- and insert it in the element list, with the
2010 -- propoer value.
2012 if The_Array_Element = No_Array_Element then
2013 Array_Element_Table.Increment_Last
2014 (In_Tree.Array_Elements);
2015 The_Array_Element := Array_Element_Table.Last
2016 (In_Tree.Array_Elements);
2018 In_Tree.Array_Elements.Table
2019 (The_Array_Element) :=
2020 (Index => Index_Name,
2021 Src_Index =>
2022 Source_Index_Of
2023 (Current_Item, From_Project_Node_Tree),
2024 Index_Case_Sensitive =>
2025 not Case_Insensitive
2026 (Current_Item, From_Project_Node_Tree),
2027 Value => New_Value,
2028 Next => In_Tree.Arrays.Table
2029 (The_Array).Value);
2030 In_Tree.Arrays.Table
2031 (The_Array).Value := The_Array_Element;
2033 -- An element with the same index already exists,
2034 -- just replace its value with the new one.
2036 else
2037 In_Tree.Array_Elements.Table
2038 (The_Array_Element).Value := New_Value;
2039 end if;
2040 end;
2041 end if;
2042 end;
2043 end if;
2045 when N_Case_Construction =>
2046 declare
2047 The_Project : Project_Id := Project;
2048 -- The id of the project of the case variable
2050 The_Package : Package_Id := Pkg;
2051 -- The id of the package, if any, of the case variable
2053 The_Variable : Variable_Value := Nil_Variable_Value;
2054 -- The case variable
2056 Case_Value : Name_Id := No_Name;
2057 -- The case variable value
2059 Case_Item : Project_Node_Id := Empty_Node;
2060 Choice_String : Project_Node_Id := Empty_Node;
2061 Decl_Item : Project_Node_Id := Empty_Node;
2063 begin
2064 declare
2065 Variable_Node : constant Project_Node_Id :=
2066 Case_Variable_Reference_Of
2067 (Current_Item,
2068 From_Project_Node_Tree);
2070 Var_Id : Variable_Id := No_Variable;
2071 Name : Name_Id := No_Name;
2073 begin
2074 -- If a project was specified for the case variable,
2075 -- get its id.
2077 if Project_Node_Of
2078 (Variable_Node, From_Project_Node_Tree) /= Empty_Node
2079 then
2080 Name :=
2081 Name_Of
2082 (Project_Node_Of
2083 (Variable_Node, From_Project_Node_Tree),
2084 From_Project_Node_Tree);
2085 The_Project :=
2086 Imported_Or_Extended_Project_From
2087 (Project, In_Tree, Name);
2088 end if;
2090 -- If a package were specified for the case variable,
2091 -- get its id.
2093 if Package_Node_Of
2094 (Variable_Node, From_Project_Node_Tree) /= Empty_Node
2095 then
2096 Name :=
2097 Name_Of
2098 (Package_Node_Of
2099 (Variable_Node, From_Project_Node_Tree),
2100 From_Project_Node_Tree);
2101 The_Package :=
2102 Package_From (The_Project, In_Tree, Name);
2103 end if;
2105 Name := Name_Of (Variable_Node, From_Project_Node_Tree);
2107 -- First, look for the case variable into the package,
2108 -- if any.
2110 if The_Package /= No_Package then
2111 Var_Id := In_Tree.Packages.Table
2112 (The_Package).Decl.Variables;
2113 Name :=
2114 Name_Of (Variable_Node, From_Project_Node_Tree);
2115 while Var_Id /= No_Variable
2116 and then
2117 In_Tree.Variable_Elements.Table
2118 (Var_Id).Name /= Name
2119 loop
2120 Var_Id := In_Tree.Variable_Elements.
2121 Table (Var_Id).Next;
2122 end loop;
2123 end if;
2125 -- If not found in the package, or if there is no
2126 -- package, look at the project level.
2128 if Var_Id = No_Variable
2129 and then
2130 Package_Node_Of
2131 (Variable_Node, From_Project_Node_Tree) = Empty_Node
2132 then
2133 Var_Id := In_Tree.Projects.Table
2134 (The_Project).Decl.Variables;
2135 while Var_Id /= No_Variable
2136 and then
2137 In_Tree.Variable_Elements.Table
2138 (Var_Id).Name /= Name
2139 loop
2140 Var_Id := In_Tree.Variable_Elements.
2141 Table (Var_Id).Next;
2142 end loop;
2143 end if;
2145 if Var_Id = No_Variable then
2147 -- Should never happen, because this has already been
2148 -- checked during parsing.
2150 Write_Line ("variable """ &
2151 Get_Name_String (Name) &
2152 """ not found");
2153 raise Program_Error;
2154 end if;
2156 -- Get the case variable
2158 The_Variable := In_Tree.Variable_Elements.
2159 Table (Var_Id).Value;
2161 if The_Variable.Kind /= Single then
2163 -- Should never happen, because this has already been
2164 -- checked during parsing.
2166 Write_Line ("variable""" &
2167 Get_Name_String (Name) &
2168 """ is not a single string variable");
2169 raise Program_Error;
2170 end if;
2172 -- Get the case variable value
2173 Case_Value := The_Variable.Value;
2174 end;
2176 -- Now look into all the case items of the case construction
2178 Case_Item :=
2179 First_Case_Item_Of (Current_Item, From_Project_Node_Tree);
2180 Case_Item_Loop :
2181 while Case_Item /= Empty_Node loop
2182 Choice_String :=
2183 First_Choice_Of (Case_Item, From_Project_Node_Tree);
2185 -- When Choice_String is nil, it means that it is
2186 -- the "when others =>" alternative.
2188 if Choice_String = Empty_Node then
2189 Decl_Item :=
2190 First_Declarative_Item_Of
2191 (Case_Item, From_Project_Node_Tree);
2192 exit Case_Item_Loop;
2193 end if;
2195 -- Look into all the alternative of this case item
2197 Choice_Loop :
2198 while Choice_String /= Empty_Node loop
2199 if Case_Value =
2200 String_Value_Of
2201 (Choice_String, From_Project_Node_Tree)
2202 then
2203 Decl_Item :=
2204 First_Declarative_Item_Of
2205 (Case_Item, From_Project_Node_Tree);
2206 exit Case_Item_Loop;
2207 end if;
2209 Choice_String :=
2210 Next_Literal_String
2211 (Choice_String, From_Project_Node_Tree);
2212 end loop Choice_Loop;
2214 Case_Item :=
2215 Next_Case_Item (Case_Item, From_Project_Node_Tree);
2216 end loop Case_Item_Loop;
2218 -- If there is an alternative, then we process it
2220 if Decl_Item /= Empty_Node then
2221 Process_Declarative_Items
2222 (Project => Project,
2223 In_Tree => In_Tree,
2224 From_Project_Node => From_Project_Node,
2225 From_Project_Node_Tree => From_Project_Node_Tree,
2226 Pkg => Pkg,
2227 Item => Decl_Item);
2228 end if;
2229 end;
2231 when others =>
2233 -- Should never happen
2235 Write_Line ("Illegal declarative item: " &
2236 Project_Node_Kind'Image
2237 (Kind_Of
2238 (Current_Item, From_Project_Node_Tree)));
2239 raise Program_Error;
2240 end case;
2241 end loop;
2242 end Process_Declarative_Items;
2244 ----------------------------------
2245 -- Process_Project_Tree_Phase_1 --
2246 ----------------------------------
2248 procedure Process_Project_Tree_Phase_1
2249 (In_Tree : Project_Tree_Ref;
2250 Project : out Project_Id;
2251 Success : out Boolean;
2252 From_Project_Node : Project_Node_Id;
2253 From_Project_Node_Tree : Project_Node_Tree_Ref;
2254 Report_Error : Put_Line_Access;
2255 Reset_Tree : Boolean := True)
2257 begin
2258 Error_Report := Report_Error;
2260 if Reset_Tree then
2262 -- Make sure there are no projects in the data structure
2264 Project_Table.Set_Last (In_Tree.Projects, No_Project);
2265 end if;
2267 Processed_Projects.Reset;
2269 -- And process the main project and all of the projects it depends on,
2270 -- recursively.
2272 Recursive_Process
2273 (Project => Project,
2274 In_Tree => In_Tree,
2275 From_Project_Node => From_Project_Node,
2276 From_Project_Node_Tree => From_Project_Node_Tree,
2277 Extended_By => No_Project);
2279 Success :=
2280 Total_Errors_Detected = 0
2281 and then
2282 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2283 end Process_Project_Tree_Phase_1;
2285 ----------------------------------
2286 -- Process_Project_Tree_Phase_2 --
2287 ----------------------------------
2289 procedure Process_Project_Tree_Phase_2
2290 (In_Tree : Project_Tree_Ref;
2291 Project : Project_Id;
2292 Success : out Boolean;
2293 From_Project_Node : Project_Node_Id;
2294 From_Project_Node_Tree : Project_Node_Tree_Ref;
2295 Report_Error : Put_Line_Access;
2296 When_No_Sources : Error_Warning := Error;
2297 Current_Dir : String)
2299 Obj_Dir : Path_Name_Type;
2300 Extending : Project_Id;
2301 Extending2 : Project_Id;
2303 -- Start of processing for Process_Project_Tree_Phase_2
2305 begin
2306 Error_Report := Report_Error;
2307 Success := True;
2309 if Project /= No_Project then
2310 Check (In_Tree, Project, Current_Dir, When_No_Sources);
2311 end if;
2313 -- If main project is an extending all project, set the object
2314 -- directory of all virtual extending projects to the object
2315 -- directory of the main project.
2317 if Project /= No_Project
2318 and then
2319 Is_Extending_All (From_Project_Node, From_Project_Node_Tree)
2320 then
2321 declare
2322 Object_Dir : constant Path_Name_Type :=
2323 In_Tree.Projects.Table
2324 (Project).Object_Directory;
2325 begin
2326 for Index in
2327 Project_Table.First .. Project_Table.Last (In_Tree.Projects)
2328 loop
2329 if In_Tree.Projects.Table (Index).Virtual then
2330 In_Tree.Projects.Table (Index).Object_Directory :=
2331 Object_Dir;
2332 end if;
2333 end loop;
2334 end;
2335 end if;
2337 -- Check that no extending project shares its object directory with
2338 -- the project(s) it extends.
2340 if Project /= No_Project then
2341 for Proj in
2342 Project_Table.First .. Project_Table.Last (In_Tree.Projects)
2343 loop
2344 Extending := In_Tree.Projects.Table (Proj).Extended_By;
2346 if Extending /= No_Project then
2347 Obj_Dir := In_Tree.Projects.Table (Proj).Object_Directory;
2349 -- Check that a project being extended does not share its
2350 -- object directory with any project that extends it, directly
2351 -- or indirectly, including a virtual extending project.
2353 -- Start with the project directly extending it
2355 Extending2 := Extending;
2356 while Extending2 /= No_Project loop
2357 if In_Tree.Projects.Table (Extending2).Ada_Sources /=
2358 Nil_String
2359 and then
2360 In_Tree.Projects.Table (Extending2).Object_Directory =
2361 Obj_Dir
2362 then
2363 if In_Tree.Projects.Table (Extending2).Virtual then
2364 Error_Msg_Name_1 :=
2365 In_Tree.Projects.Table (Proj).Display_Name;
2367 if Error_Report = null then
2368 Error_Msg
2369 ("project %% cannot be extended by a virtual" &
2370 " project with the same object directory",
2371 In_Tree.Projects.Table (Proj).Location);
2372 else
2373 Error_Report
2374 ("project """ &
2375 Get_Name_String (Error_Msg_Name_1) &
2376 """ cannot be extended by a virtual " &
2377 "project with the same object directory",
2378 Project, In_Tree);
2379 end if;
2381 else
2382 Error_Msg_Name_1 :=
2383 In_Tree.Projects.Table (Extending2).Display_Name;
2384 Error_Msg_Name_2 :=
2385 In_Tree.Projects.Table (Proj).Display_Name;
2387 if Error_Report = null then
2388 Error_Msg
2389 ("project %% cannot extend project %%",
2390 In_Tree.Projects.Table (Extending2).Location);
2391 Error_Msg
2392 ("\they share the same object directory",
2393 In_Tree.Projects.Table (Extending2).Location);
2395 else
2396 Error_Report
2397 ("project """ &
2398 Get_Name_String (Error_Msg_Name_1) &
2399 """ cannot extend project """ &
2400 Get_Name_String (Error_Msg_Name_2) & """",
2401 Project, In_Tree);
2402 Error_Report
2403 ("they share the same object directory",
2404 Project, In_Tree);
2405 end if;
2406 end if;
2407 end if;
2409 -- Continue with the next extending project, if any
2411 Extending2 :=
2412 In_Tree.Projects.Table (Extending2).Extended_By;
2413 end loop;
2414 end if;
2415 end loop;
2416 end if;
2418 Success :=
2419 Total_Errors_Detected = 0
2420 and then
2421 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2422 end Process_Project_Tree_Phase_2;
2424 ---------------------
2425 -- Recursive_Check --
2426 ---------------------
2428 procedure Recursive_Check
2429 (Project : Project_Id;
2430 In_Tree : Project_Tree_Ref;
2431 Current_Dir : String;
2432 When_No_Sources : Error_Warning)
2434 Data : Project_Data;
2435 Imported_Project_List : Project_List := Empty_Project_List;
2437 begin
2438 -- Do nothing if Project is No_Project, or Project has already
2439 -- been marked as checked.
2441 if Project /= No_Project
2442 and then not In_Tree.Projects.Table (Project).Checked
2443 then
2444 -- Mark project as checked, to avoid infinite recursion in
2445 -- ill-formed trees, where a project imports itself.
2447 In_Tree.Projects.Table (Project).Checked := True;
2449 Data := In_Tree.Projects.Table (Project);
2451 -- Call itself for a possible extended project.
2452 -- (if there is no extended project, then nothing happens).
2454 Recursive_Check (Data.Extends, In_Tree, Current_Dir, When_No_Sources);
2456 -- Call itself for all imported projects
2458 Imported_Project_List := Data.Imported_Projects;
2459 while Imported_Project_List /= Empty_Project_List loop
2460 Recursive_Check
2461 (In_Tree.Project_Lists.Table
2462 (Imported_Project_List).Project,
2463 In_Tree, Current_Dir, When_No_Sources);
2464 Imported_Project_List :=
2465 In_Tree.Project_Lists.Table
2466 (Imported_Project_List).Next;
2467 end loop;
2469 if Verbose_Mode then
2470 Write_Str ("Checking project file """);
2471 Write_Str (Get_Name_String (Data.Name));
2472 Write_Line ("""");
2473 end if;
2475 Prj.Nmsc.Check
2476 (Project, In_Tree, Error_Report, When_No_Sources,
2477 Current_Dir);
2478 end if;
2479 end Recursive_Check;
2481 -----------------------
2482 -- Recursive_Process --
2483 -----------------------
2485 procedure Recursive_Process
2486 (In_Tree : Project_Tree_Ref;
2487 Project : out Project_Id;
2488 From_Project_Node : Project_Node_Id;
2489 From_Project_Node_Tree : Project_Node_Tree_Ref;
2490 Extended_By : Project_Id)
2492 With_Clause : Project_Node_Id;
2494 begin
2495 if From_Project_Node = Empty_Node then
2496 Project := No_Project;
2498 else
2499 declare
2500 Processed_Data : Project_Data := Empty_Project (In_Tree);
2501 Imported : Project_List := Empty_Project_List;
2502 Declaration_Node : Project_Node_Id := Empty_Node;
2503 Tref : Source_Buffer_Ptr;
2504 Name : constant Name_Id :=
2505 Name_Of
2506 (From_Project_Node, From_Project_Node_Tree);
2507 Location : Source_Ptr :=
2508 Location_Of
2509 (From_Project_Node, From_Project_Node_Tree);
2511 begin
2512 Project := Processed_Projects.Get (Name);
2514 if Project /= No_Project then
2516 -- Make sure that, when a project is extended, the project id
2517 -- of the project extending it is recorded in its data, even
2518 -- when it has already been processed as an imported project.
2519 -- This is for virtually extended projects.
2521 if Extended_By /= No_Project then
2522 In_Tree.Projects.Table (Project).Extended_By := Extended_By;
2523 end if;
2525 return;
2526 end if;
2528 Project_Table.Increment_Last (In_Tree.Projects);
2529 Project := Project_Table.Last (In_Tree.Projects);
2530 Processed_Projects.Set (Name, Project);
2532 Processed_Data.Name := Name;
2534 Get_Name_String (Name);
2536 -- If name starts with the virtual prefix, flag the project as
2537 -- being a virtual extending project.
2539 if Name_Len > Virtual_Prefix'Length
2540 and then Name_Buffer (1 .. Virtual_Prefix'Length) =
2541 Virtual_Prefix
2542 then
2543 Processed_Data.Virtual := True;
2544 Processed_Data.Display_Name := Name;
2546 -- If there is no file, for example when the project node tree is
2547 -- built in memory by GPS, the Display_Name cannot be found in
2548 -- the source, so its value is the same as Name.
2550 elsif Location = No_Location then
2551 Processed_Data.Display_Name := Name;
2553 -- Get the spelling of the project name from the project file
2555 else
2556 Tref := Source_Text (Get_Source_File_Index (Location));
2558 for J in 1 .. Name_Len loop
2559 Name_Buffer (J) := Tref (Location);
2560 Location := Location + 1;
2561 end loop;
2563 Processed_Data.Display_Name := Name_Find;
2564 end if;
2566 Processed_Data.Display_Path_Name :=
2567 Path_Name_Of (From_Project_Node, From_Project_Node_Tree);
2568 Get_Name_String (Processed_Data.Display_Path_Name);
2569 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2570 Processed_Data.Path_Name := Name_Find;
2572 Processed_Data.Location :=
2573 Location_Of (From_Project_Node, From_Project_Node_Tree);
2575 Processed_Data.Display_Directory :=
2576 Directory_Of (From_Project_Node, From_Project_Node_Tree);
2577 Get_Name_String (Processed_Data.Display_Directory);
2578 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2579 Processed_Data.Directory := Name_Find;
2581 Processed_Data.Extended_By := Extended_By;
2583 Add_Attributes
2584 (Project,
2585 Name,
2586 In_Tree,
2587 Processed_Data.Decl,
2588 Prj.Attr.Attribute_First,
2589 Project_Level => True);
2591 With_Clause :=
2592 First_With_Clause_Of (From_Project_Node, From_Project_Node_Tree);
2593 while With_Clause /= Empty_Node loop
2594 declare
2595 New_Project : Project_Id;
2596 New_Data : Project_Data;
2598 begin
2599 Recursive_Process
2600 (In_Tree => In_Tree,
2601 Project => New_Project,
2602 From_Project_Node =>
2603 Project_Node_Of (With_Clause, From_Project_Node_Tree),
2604 From_Project_Node_Tree => From_Project_Node_Tree,
2605 Extended_By => No_Project);
2606 New_Data :=
2607 In_Tree.Projects.Table (New_Project);
2609 -- If we were the first project to import it,
2610 -- set First_Referred_By to us.
2612 if New_Data.First_Referred_By = No_Project then
2613 New_Data.First_Referred_By := Project;
2614 In_Tree.Projects.Table (New_Project) :=
2615 New_Data;
2616 end if;
2618 -- Add this project to our list of imported projects
2620 Project_List_Table.Increment_Last
2621 (In_Tree.Project_Lists);
2622 In_Tree.Project_Lists.Table
2623 (Project_List_Table.Last
2624 (In_Tree.Project_Lists)) :=
2625 (Project => New_Project, Next => Empty_Project_List);
2627 -- Imported is the id of the last imported project.
2628 -- If it is nil, then this imported project is our first.
2630 if Imported = Empty_Project_List then
2631 Processed_Data.Imported_Projects :=
2632 Project_List_Table.Last
2633 (In_Tree.Project_Lists);
2635 else
2636 In_Tree.Project_Lists.Table
2637 (Imported).Next := Project_List_Table.Last
2638 (In_Tree.Project_Lists);
2639 end if;
2641 Imported := Project_List_Table.Last
2642 (In_Tree.Project_Lists);
2644 With_Clause :=
2645 Next_With_Clause_Of (With_Clause, From_Project_Node_Tree);
2646 end;
2647 end loop;
2649 Declaration_Node :=
2650 Project_Declaration_Of
2651 (From_Project_Node, From_Project_Node_Tree);
2653 Recursive_Process
2654 (In_Tree => In_Tree,
2655 Project => Processed_Data.Extends,
2656 From_Project_Node => Extended_Project_Of
2657 (Declaration_Node,
2658 From_Project_Node_Tree),
2659 From_Project_Node_Tree => From_Project_Node_Tree,
2660 Extended_By => Project);
2662 In_Tree.Projects.Table (Project) := Processed_Data;
2664 Process_Declarative_Items
2665 (Project => Project,
2666 In_Tree => In_Tree,
2667 From_Project_Node => From_Project_Node,
2668 From_Project_Node_Tree => From_Project_Node_Tree,
2669 Pkg => No_Package,
2670 Item => First_Declarative_Item_Of
2671 (Declaration_Node,
2672 From_Project_Node_Tree));
2674 -- If it is an extending project, inherit all packages
2675 -- from the extended project that are not explicitely defined
2676 -- or renamed. Also inherit the languages, if attribute Languages
2677 -- is not explicitely defined.
2679 if Processed_Data.Extends /= No_Project then
2680 Processed_Data := In_Tree.Projects.Table (Project);
2682 declare
2683 Extended_Pkg : Package_Id;
2684 Current_Pkg : Package_Id;
2685 Element : Package_Element;
2686 First : constant Package_Id :=
2687 Processed_Data.Decl.Packages;
2688 Attribute1 : Variable_Id;
2689 Attribute2 : Variable_Id;
2690 Attr_Value1 : Variable;
2691 Attr_Value2 : Variable;
2693 begin
2694 Extended_Pkg :=
2695 In_Tree.Projects.Table
2696 (Processed_Data.Extends).Decl.Packages;
2697 while Extended_Pkg /= No_Package loop
2698 Element :=
2699 In_Tree.Packages.Table (Extended_Pkg);
2701 Current_Pkg := First;
2702 while Current_Pkg /= No_Package
2703 and then In_Tree.Packages.Table (Current_Pkg).Name /=
2704 Element.Name
2705 loop
2706 Current_Pkg :=
2707 In_Tree.Packages.Table (Current_Pkg).Next;
2708 end loop;
2710 if Current_Pkg = No_Package then
2711 Package_Table.Increment_Last
2712 (In_Tree.Packages);
2713 Current_Pkg := Package_Table.Last (In_Tree.Packages);
2714 In_Tree.Packages.Table (Current_Pkg) :=
2715 (Name => Element.Name,
2716 Decl => No_Declarations,
2717 Parent => No_Package,
2718 Next => Processed_Data.Decl.Packages);
2719 Processed_Data.Decl.Packages := Current_Pkg;
2720 Copy_Package_Declarations
2721 (From => Element.Decl,
2722 To => In_Tree.Packages.Table (Current_Pkg).Decl,
2723 New_Loc => No_Location,
2724 In_Tree => In_Tree);
2725 end if;
2727 Extended_Pkg := Element.Next;
2728 end loop;
2730 -- Check if attribute Languages is declared in the
2731 -- extending project.
2733 Attribute1 := Processed_Data.Decl.Attributes;
2734 while Attribute1 /= No_Variable loop
2735 Attr_Value1 := In_Tree.Variable_Elements.
2736 Table (Attribute1);
2737 exit when Attr_Value1.Name = Snames.Name_Languages;
2738 Attribute1 := Attr_Value1.Next;
2739 end loop;
2741 if Attribute1 = No_Variable or else
2742 Attr_Value1.Value.Default
2743 then
2744 -- Attribute Languages is not declared in the extending
2745 -- project. Check if it is declared in the project being
2746 -- extended.
2748 Attribute2 :=
2749 In_Tree.Projects.Table
2750 (Processed_Data.Extends).Decl.Attributes;
2751 while Attribute2 /= No_Variable loop
2752 Attr_Value2 := In_Tree.Variable_Elements.
2753 Table (Attribute2);
2754 exit when Attr_Value2.Name = Snames.Name_Languages;
2755 Attribute2 := Attr_Value2.Next;
2756 end loop;
2758 if Attribute2 /= No_Variable and then
2759 not Attr_Value2.Value.Default
2760 then
2761 -- As attribute Languages is declared in the project
2762 -- being extended, copy its value for the extending
2763 -- project.
2765 if Attribute1 = No_Variable then
2766 Variable_Element_Table.Increment_Last
2767 (In_Tree.Variable_Elements);
2768 Attribute1 := Variable_Element_Table.Last
2769 (In_Tree.Variable_Elements);
2770 Attr_Value1.Next := Processed_Data.Decl.Attributes;
2771 Processed_Data.Decl.Attributes := Attribute1;
2772 end if;
2774 Attr_Value1.Name := Snames.Name_Languages;
2775 Attr_Value1.Value := Attr_Value2.Value;
2776 In_Tree.Variable_Elements.Table
2777 (Attribute1) := Attr_Value1;
2778 end if;
2779 end if;
2780 end;
2782 In_Tree.Projects.Table (Project) := Processed_Data;
2783 end if;
2784 end;
2785 end if;
2786 end Recursive_Process;
2788 end Prj.Proc;