File : prj-proc.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . P R O C --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2015, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Atree; use Atree;
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.Env;
33 with Prj.Err; use Prj.Err;
34 with Prj.Ext; use Prj.Ext;
35 with Prj.Nmsc; use Prj.Nmsc;
36 with Prj.Part;
37 with Prj.Util;
38 with Snames;
39
40 with Ada.Containers.Vectors;
41 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
42
43 with GNAT.Case_Util; use GNAT.Case_Util;
44 with GNAT.HTable;
45
46 package body Prj.Proc is
47
48 package Processed_Projects is new GNAT.HTable.Simple_HTable
49 (Header_Num => Header_Num,
50 Element => Project_Id,
51 No_Element => No_Project,
52 Key => Name_Id,
53 Hash => Hash,
54 Equal => "=");
55 -- This hash table contains all processed projects
56
57 package Unit_Htable is new GNAT.HTable.Simple_HTable
58 (Header_Num => Header_Num,
59 Element => Source_Id,
60 No_Element => No_Source,
61 Key => Name_Id,
62 Hash => Hash,
63 Equal => "=");
64 -- This hash table contains all processed projects
65
66 package Runtime_Defaults is new GNAT.HTable.Simple_HTable
67 (Header_Num => Prj.Header_Num,
68 Element => Name_Id,
69 No_Element => No_Name,
70 Key => Name_Id,
71 Hash => Prj.Hash,
72 Equal => "=");
73 -- Stores the default values of 'Runtime names for the various languages
74
75 procedure Add (To_Exp : in out Name_Id; Str : Name_Id);
76 -- Concatenate two strings and returns another string if both
77 -- arguments are not null string.
78
79 -- In the following procedures, we are expected to guess the meaning of
80 -- the parameters from their names, this is never a good idea, comments
81 -- should be added precisely defining every formal ???
82
83 procedure Add_Attributes
84 (Project : Project_Id;
85 Project_Name : Name_Id;
86 Project_Dir : Name_Id;
87 Shared : Shared_Project_Tree_Data_Access;
88 Decl : in out Declarations;
89 First : Attribute_Node_Id;
90 Project_Level : Boolean);
91 -- Add all attributes, starting with First, with their default values to
92 -- the package or project with declarations Decl.
93
94 procedure Check
95 (In_Tree : Project_Tree_Ref;
96 Project : Project_Id;
97 Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
98 Flags : Processing_Flags);
99 -- Set all projects to not checked, then call Recursive_Check for the
100 -- main project Project. Project is set to No_Project if errors occurred.
101 -- Current_Dir is for optimization purposes, avoiding extra system calls.
102 -- If Allow_Duplicate_Basenames, then files with the same base names are
103 -- authorized within a project for source-based languages (never for unit
104 -- based languages)
105
106 procedure Copy_Package_Declarations
107 (From : Declarations;
108 To : in out Declarations;
109 New_Loc : Source_Ptr;
110 Restricted : Boolean;
111 Shared : Shared_Project_Tree_Data_Access);
112 -- Copy a package declaration From to To for a renamed package. Change the
113 -- locations of all the attributes to New_Loc. When Restricted is
114 -- True, do not copy attributes Body, Spec, Implementation, Specification
115 -- and Linker_Options.
116
117 function Expression
118 (Project : Project_Id;
119 Shared : Shared_Project_Tree_Data_Access;
120 From_Project_Node : Project_Node_Id;
121 From_Project_Node_Tree : Project_Node_Tree_Ref;
122 Env : Prj.Tree.Environment;
123 Pkg : Package_Id;
124 First_Term : Project_Node_Id;
125 Kind : Variable_Kind) return Variable_Value;
126 -- From N_Expression project node From_Project_Node, compute the value
127 -- of an expression and return it as a Variable_Value.
128
129 function Imported_Or_Extended_Project_From
130 (Project : Project_Id;
131 With_Name : Name_Id;
132 No_Extending : Boolean := False) return Project_Id;
133 -- Find an imported or extended project of Project whose name is With_Name.
134 -- When No_Extending is True, do not look for extending projects, returns
135 -- the exact project whose name is With_Name.
136
137 function Package_From
138 (Project : Project_Id;
139 Shared : Shared_Project_Tree_Data_Access;
140 With_Name : Name_Id) return Package_Id;
141 -- Find the package of Project whose name is With_Name
142
143 procedure Process_Declarative_Items
144 (Project : Project_Id;
145 In_Tree : Project_Tree_Ref;
146 From_Project_Node : Project_Node_Id;
147 Node_Tree : Project_Node_Tree_Ref;
148 Env : Prj.Tree.Environment;
149 Pkg : Package_Id;
150 Item : Project_Node_Id;
151 Child_Env : in out Prj.Tree.Environment);
152 -- Process declarative items starting with From_Project_Node, and put them
153 -- in declarations Decl. This is a recursive procedure; it calls itself for
154 -- a package declaration or a case construction.
155 --
156 -- Child_Env is the modified environment after seeing declarations like
157 -- "for External(...) use" or "for Project_Path use" in aggregate projects.
158 -- It should have been initialized first.
159
160 procedure Recursive_Process
161 (In_Tree : Project_Tree_Ref;
162 Project : out Project_Id;
163 Packages_To_Check : String_List_Access;
164 From_Project_Node : Project_Node_Id;
165 From_Project_Node_Tree : Project_Node_Tree_Ref;
166 Env : in out Prj.Tree.Environment;
167 Extended_By : Project_Id;
168 From_Encapsulated_Lib : Boolean;
169 On_New_Tree_Loaded : Tree_Loaded_Callback := null);
170 -- Process project with node From_Project_Node in the tree. Do nothing if
171 -- From_Project_Node is Empty_Node. If project has already been processed,
172 -- simply return its project id. Otherwise create a new project id, mark it
173 -- as processed, call itself recursively for all imported projects and a
174 -- extended project, if any. Then process the declarative items of the
175 -- project.
176 --
177 -- Is_Root_Project should be true only for the project that the user
178 -- explicitly loaded. In the context of aggregate projects, only that
179 -- project is allowed to modify the environment that will be used to load
180 -- projects (Child_Env).
181 --
182 -- From_Encapsulated_Lib is true if we are parsing a project from
183 -- encapsulated library dependencies.
184 --
185 -- If specified, On_New_Tree_Loaded is called after each aggregated project
186 -- has been processed succesfully.
187
188 function Get_Attribute_Index
189 (Tree : Project_Node_Tree_Ref;
190 Attr : Project_Node_Id;
191 Index : Name_Id) return Name_Id;
192 -- Copy the index of the attribute into Name_Buffer, converting to lower
193 -- case if the attribute is case-insensitive.
194
195 ---------
196 -- Add --
197 ---------
198
199 procedure Add (To_Exp : in out Name_Id; Str : Name_Id) is
200 begin
201 if To_Exp = No_Name or else To_Exp = Empty_String then
202
203 -- To_Exp is nil or empty. The result is Str
204
205 To_Exp := Str;
206
207 -- If Str is nil, then do not change To_Ext
208
209 elsif Str /= No_Name and then Str /= Empty_String then
210 declare
211 S : constant String := Get_Name_String (Str);
212 begin
213 Get_Name_String (To_Exp);
214 Add_Str_To_Name_Buffer (S);
215 To_Exp := Name_Find;
216 end;
217 end if;
218 end Add;
219
220 --------------------
221 -- Add_Attributes --
222 --------------------
223
224 procedure Add_Attributes
225 (Project : Project_Id;
226 Project_Name : Name_Id;
227 Project_Dir : Name_Id;
228 Shared : Shared_Project_Tree_Data_Access;
229 Decl : in out Declarations;
230 First : Attribute_Node_Id;
231 Project_Level : Boolean)
232 is
233 The_Attribute : Attribute_Node_Id := First;
234
235 begin
236 while The_Attribute /= Empty_Attribute loop
237 if Attribute_Kind_Of (The_Attribute) = Single then
238 declare
239 New_Attribute : Variable_Value;
240
241 begin
242 case Variable_Kind_Of (The_Attribute) is
243
244 -- Undefined should not happen
245
246 when Undefined =>
247 pragma Assert
248 (False, "attribute with an undefined kind");
249 raise Program_Error;
250
251 -- Single attributes have a default value of empty string
252
253 when Single =>
254 New_Attribute :=
255 (Project => Project,
256 Kind => Single,
257 Location => No_Location,
258 Default => True,
259 Value => Empty_String,
260 Index => 0);
261
262 -- Special cases of <project>'Name and
263 -- <project>'Project_Dir.
264
265 if Project_Level then
266 if Attribute_Name_Of (The_Attribute) =
267 Snames.Name_Name
268 then
269 New_Attribute.Value := Project_Name;
270
271 elsif Attribute_Name_Of (The_Attribute) =
272 Snames.Name_Project_Dir
273 then
274 New_Attribute.Value := Project_Dir;
275 end if;
276 end if;
277
278 -- List attributes have a default value of nil list
279
280 when List =>
281 New_Attribute :=
282 (Project => Project,
283 Kind => List,
284 Location => No_Location,
285 Default => True,
286 Values => Nil_String);
287
288 end case;
289
290 Variable_Element_Table.Increment_Last
291 (Shared.Variable_Elements);
292 Shared.Variable_Elements.Table
293 (Variable_Element_Table.Last (Shared.Variable_Elements)) :=
294 (Next => Decl.Attributes,
295 Name => Attribute_Name_Of (The_Attribute),
296 Value => New_Attribute);
297 Decl.Attributes :=
298 Variable_Element_Table.Last
299 (Shared.Variable_Elements);
300 end;
301 end if;
302
303 The_Attribute := Next_Attribute (After => The_Attribute);
304 end loop;
305 end Add_Attributes;
306
307 -----------
308 -- Check --
309 -----------
310
311 procedure Check
312 (In_Tree : Project_Tree_Ref;
313 Project : Project_Id;
314 Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
315 Flags : Processing_Flags)
316 is
317 begin
318 Process_Naming_Scheme (In_Tree, Project, Node_Tree, Flags);
319
320 -- Set the Other_Part field for the units
321
322 declare
323 Source1 : Source_Id;
324 Name : Name_Id;
325 Source2 : Source_Id;
326 Iter : Source_Iterator;
327
328 begin
329 Unit_Htable.Reset;
330
331 Iter := For_Each_Source (In_Tree);
332 loop
333 Source1 := Prj.Element (Iter);
334 exit when Source1 = No_Source;
335
336 if Source1.Unit /= No_Unit_Index then
337 Name := Source1.Unit.Name;
338 Source2 := Unit_Htable.Get (Name);
339
340 if Source2 = No_Source then
341 Unit_Htable.Set (K => Name, E => Source1);
342 else
343 Unit_Htable.Remove (Name);
344 end if;
345 end if;
346
347 Next (Iter);
348 end loop;
349 end;
350 end Check;
351
352 -------------------------------
353 -- Copy_Package_Declarations --
354 -------------------------------
355
356 procedure Copy_Package_Declarations
357 (From : Declarations;
358 To : in out Declarations;
359 New_Loc : Source_Ptr;
360 Restricted : Boolean;
361 Shared : Shared_Project_Tree_Data_Access)
362 is
363 V1 : Variable_Id;
364 V2 : Variable_Id := No_Variable;
365 Var : Variable;
366 A1 : Array_Id;
367 A2 : Array_Id := No_Array;
368 Arr : Array_Data;
369 E1 : Array_Element_Id;
370 E2 : Array_Element_Id := No_Array_Element;
371 Elm : Array_Element;
372
373 begin
374 -- To avoid references in error messages to attribute declarations in
375 -- an original package that has been renamed, copy all the attribute
376 -- declarations of the package and change all locations to New_Loc,
377 -- the location of the renamed package.
378
379 -- First single attributes
380
381 V1 := From.Attributes;
382 while V1 /= No_Variable loop
383
384 -- Copy the attribute
385
386 Var := Shared.Variable_Elements.Table (V1);
387 V1 := Var.Next;
388
389 -- Do not copy the value of attribute Linker_Options if Restricted
390
391 if Restricted and then Var.Name = Snames.Name_Linker_Options then
392 Var.Value.Values := Nil_String;
393 end if;
394
395 -- Remove the Next component
396
397 Var.Next := No_Variable;
398
399 -- Change the location to New_Loc
400
401 Var.Value.Location := New_Loc;
402 Variable_Element_Table.Increment_Last (Shared.Variable_Elements);
403
404 -- Put in new declaration
405
406 if To.Attributes = No_Variable then
407 To.Attributes :=
408 Variable_Element_Table.Last (Shared.Variable_Elements);
409 else
410 Shared.Variable_Elements.Table (V2).Next :=
411 Variable_Element_Table.Last (Shared.Variable_Elements);
412 end if;
413
414 V2 := Variable_Element_Table.Last (Shared.Variable_Elements);
415 Shared.Variable_Elements.Table (V2) := Var;
416 end loop;
417
418 -- Then the associated array attributes
419
420 A1 := From.Arrays;
421 while A1 /= No_Array loop
422 Arr := Shared.Arrays.Table (A1);
423 A1 := Arr.Next;
424
425 -- Remove the Next component
426
427 Arr.Next := No_Array;
428 Array_Table.Increment_Last (Shared.Arrays);
429
430 -- Create new Array declaration
431
432 if To.Arrays = No_Array then
433 To.Arrays := Array_Table.Last (Shared.Arrays);
434 else
435 Shared.Arrays.Table (A2).Next :=
436 Array_Table.Last (Shared.Arrays);
437 end if;
438
439 A2 := Array_Table.Last (Shared.Arrays);
440
441 -- Don't store the array as its first element has not been set yet
442
443 -- Copy the array elements of the array
444
445 E1 := Arr.Value;
446 Arr.Value := No_Array_Element;
447 while E1 /= No_Array_Element loop
448
449 -- Copy the array element
450
451 Elm := Shared.Array_Elements.Table (E1);
452 E1 := Elm.Next;
453
454 -- Remove the Next component
455
456 Elm.Next := No_Array_Element;
457
458 Elm.Restricted := Restricted;
459
460 -- Change the location
461
462 Elm.Value.Location := New_Loc;
463 Array_Element_Table.Increment_Last (Shared.Array_Elements);
464
465 -- Create new array element
466
467 if Arr.Value = No_Array_Element then
468 Arr.Value := Array_Element_Table.Last (Shared.Array_Elements);
469 else
470 Shared.Array_Elements.Table (E2).Next :=
471 Array_Element_Table.Last (Shared.Array_Elements);
472 end if;
473
474 E2 := Array_Element_Table.Last (Shared.Array_Elements);
475 Shared.Array_Elements.Table (E2) := Elm;
476 end loop;
477
478 -- Finally, store the new array
479
480 Shared.Arrays.Table (A2) := Arr;
481 end loop;
482 end Copy_Package_Declarations;
483
484 -------------------------
485 -- Get_Attribute_Index --
486 -------------------------
487
488 function Get_Attribute_Index
489 (Tree : Project_Node_Tree_Ref;
490 Attr : Project_Node_Id;
491 Index : Name_Id) return Name_Id
492 is
493 begin
494 if Index = All_Other_Names
495 or else not Case_Insensitive (Attr, Tree)
496 then
497 return Index;
498 end if;
499
500 Get_Name_String (Index);
501 To_Lower (Name_Buffer (1 .. Name_Len));
502 return Name_Find;
503 end Get_Attribute_Index;
504
505 ----------------
506 -- Expression --
507 ----------------
508
509 function Expression
510 (Project : Project_Id;
511 Shared : Shared_Project_Tree_Data_Access;
512 From_Project_Node : Project_Node_Id;
513 From_Project_Node_Tree : Project_Node_Tree_Ref;
514 Env : Prj.Tree.Environment;
515 Pkg : Package_Id;
516 First_Term : Project_Node_Id;
517 Kind : Variable_Kind) return Variable_Value
518 is
519 The_Term : Project_Node_Id;
520 -- The term in the expression list
521
522 The_Current_Term : Project_Node_Id := Empty_Node;
523 -- The current term node id
524
525 Result : Variable_Value (Kind => Kind);
526 -- The returned result
527
528 Last : String_List_Id := Nil_String;
529 -- Reference to the last string elements in Result, when Kind is List
530
531 Current_Term_Kind : Project_Node_Kind;
532
533 begin
534 Result.Project := Project;
535 Result.Location := Location_Of (First_Term, From_Project_Node_Tree);
536
537 -- Process each term of the expression, starting with First_Term
538
539 The_Term := First_Term;
540 while Present (The_Term) loop
541 The_Current_Term := Current_Term (The_Term, From_Project_Node_Tree);
542
543 if The_Current_Term /= Empty_Node then
544 Current_Term_Kind :=
545 Kind_Of (The_Current_Term, From_Project_Node_Tree);
546
547 case Current_Term_Kind is
548
549 when N_Literal_String =>
550 case Kind is
551 when Undefined =>
552
553 -- Should never happen
554
555 pragma Assert (False, "Undefined expression kind");
556 raise Program_Error;
557
558 when Single =>
559 Add (Result.Value,
560 String_Value_Of
561 (The_Current_Term, From_Project_Node_Tree));
562 Result.Index :=
563 Source_Index_Of
564 (The_Current_Term, From_Project_Node_Tree);
565
566 when List =>
567
568 String_Element_Table.Increment_Last
569 (Shared.String_Elements);
570
571 if Last = Nil_String then
572
573 -- This can happen in an expression like () & "toto"
574
575 Result.Values := String_Element_Table.Last
576 (Shared.String_Elements);
577
578 else
579 Shared.String_Elements.Table
580 (Last).Next := String_Element_Table.Last
581 (Shared.String_Elements);
582 end if;
583
584 Last := String_Element_Table.Last
585 (Shared.String_Elements);
586
587 Shared.String_Elements.Table (Last) :=
588 (Value => String_Value_Of
589 (The_Current_Term,
590 From_Project_Node_Tree),
591 Index => Source_Index_Of
592 (The_Current_Term,
593 From_Project_Node_Tree),
594 Display_Value => No_Name,
595 Location => Location_Of
596 (The_Current_Term,
597 From_Project_Node_Tree),
598 Flag => False,
599 Next => Nil_String);
600 end case;
601
602 when N_Literal_String_List =>
603 declare
604 String_Node : Project_Node_Id :=
605 First_Expression_In_List
606 (The_Current_Term,
607 From_Project_Node_Tree);
608
609 Value : Variable_Value;
610
611 begin
612 if Present (String_Node) then
613
614 -- If String_Node is nil, it is an empty list, there is
615 -- nothing to do.
616
617 Value := Expression
618 (Project => Project,
619 Shared => Shared,
620 From_Project_Node => From_Project_Node,
621 From_Project_Node_Tree => From_Project_Node_Tree,
622 Env => Env,
623 Pkg => Pkg,
624 First_Term =>
625 Tree.First_Term
626 (String_Node, From_Project_Node_Tree),
627 Kind => Single);
628 String_Element_Table.Increment_Last
629 (Shared.String_Elements);
630
631 if Result.Values = Nil_String then
632
633 -- This literal string list is the first term in a
634 -- string list expression
635
636 Result.Values :=
637 String_Element_Table.Last
638 (Shared.String_Elements);
639
640 else
641 Shared.String_Elements.Table (Last).Next :=
642 String_Element_Table.Last (Shared.String_Elements);
643 end if;
644
645 Last :=
646 String_Element_Table.Last (Shared.String_Elements);
647
648 Shared.String_Elements.Table (Last) :=
649 (Value => Value.Value,
650 Display_Value => No_Name,
651 Location => Value.Location,
652 Flag => False,
653 Next => Nil_String,
654 Index => Value.Index);
655
656 loop
657 -- Add the other element of the literal string list
658 -- one after the other.
659
660 String_Node :=
661 Next_Expression_In_List
662 (String_Node, From_Project_Node_Tree);
663
664 exit when No (String_Node);
665
666 Value :=
667 Expression
668 (Project => Project,
669 Shared => Shared,
670 From_Project_Node => From_Project_Node,
671 From_Project_Node_Tree => From_Project_Node_Tree,
672 Env => Env,
673 Pkg => Pkg,
674 First_Term =>
675 Tree.First_Term
676 (String_Node, From_Project_Node_Tree),
677 Kind => Single);
678
679 String_Element_Table.Increment_Last
680 (Shared.String_Elements);
681 Shared.String_Elements.Table (Last).Next :=
682 String_Element_Table.Last (Shared.String_Elements);
683 Last := String_Element_Table.Last
684 (Shared.String_Elements);
685 Shared.String_Elements.Table (Last) :=
686 (Value => Value.Value,
687 Display_Value => No_Name,
688 Location => Value.Location,
689 Flag => False,
690 Next => Nil_String,
691 Index => Value.Index);
692 end loop;
693 end if;
694 end;
695
696 when N_Variable_Reference | N_Attribute_Reference =>
697 declare
698 The_Project : Project_Id := Project;
699 The_Package : Package_Id := Pkg;
700 The_Name : Name_Id := No_Name;
701 The_Variable_Id : Variable_Id := No_Variable;
702 The_Variable : Variable_Value;
703 Term_Project : constant Project_Node_Id :=
704 Project_Node_Of
705 (The_Current_Term,
706 From_Project_Node_Tree);
707 Term_Package : constant Project_Node_Id :=
708 Package_Node_Of
709 (The_Current_Term,
710 From_Project_Node_Tree);
711 Index : Name_Id := No_Name;
712
713 begin
714 <<Object_Dir_Restart>>
715 The_Project := Project;
716 The_Package := Pkg;
717 The_Name := No_Name;
718 The_Variable_Id := No_Variable;
719 Index := No_Name;
720
721 if Present (Term_Project)
722 and then Term_Project /= From_Project_Node
723 then
724 -- This variable or attribute comes from another project
725
726 The_Name :=
727 Name_Of (Term_Project, From_Project_Node_Tree);
728 The_Project := Imported_Or_Extended_Project_From
729 (Project => Project,
730 With_Name => The_Name,
731 No_Extending => True);
732 end if;
733
734 if Present (Term_Package) then
735
736 -- This is an attribute of a package
737
738 The_Name :=
739 Name_Of (Term_Package, From_Project_Node_Tree);
740
741 The_Package := The_Project.Decl.Packages;
742 while The_Package /= No_Package
743 and then Shared.Packages.Table (The_Package).Name /=
744 The_Name
745 loop
746 The_Package :=
747 Shared.Packages.Table (The_Package).Next;
748 end loop;
749
750 pragma Assert
751 (The_Package /= No_Package, "package not found.");
752
753 elsif Kind_Of (The_Current_Term, From_Project_Node_Tree) =
754 N_Attribute_Reference
755 then
756 The_Package := No_Package;
757 end if;
758
759 The_Name :=
760 Name_Of (The_Current_Term, From_Project_Node_Tree);
761
762 if Current_Term_Kind = N_Attribute_Reference then
763 Index :=
764 Associative_Array_Index_Of
765 (The_Current_Term, From_Project_Node_Tree);
766 end if;
767
768 -- If it is not an associative array attribute
769
770 if Index = No_Name then
771
772 -- It is not an associative array attribute
773
774 if The_Package /= No_Package then
775
776 -- First, if there is a package, look into the package
777
778 if Current_Term_Kind = N_Variable_Reference then
779 The_Variable_Id :=
780 Shared.Packages.Table
781 (The_Package).Decl.Variables;
782 else
783 The_Variable_Id :=
784 Shared.Packages.Table
785 (The_Package).Decl.Attributes;
786 end if;
787
788 while The_Variable_Id /= No_Variable
789 and then Shared.Variable_Elements.Table
790 (The_Variable_Id).Name /= The_Name
791 loop
792 The_Variable_Id :=
793 Shared.Variable_Elements.Table
794 (The_Variable_Id).Next;
795 end loop;
796
797 end if;
798
799 if The_Variable_Id = No_Variable then
800
801 -- If we have not found it, look into the project
802
803 if Current_Term_Kind = N_Variable_Reference then
804 The_Variable_Id := The_Project.Decl.Variables;
805 else
806 The_Variable_Id := The_Project.Decl.Attributes;
807 end if;
808
809 while The_Variable_Id /= No_Variable
810 and then Shared.Variable_Elements.Table
811 (The_Variable_Id).Name /= The_Name
812 loop
813 The_Variable_Id :=
814 Shared.Variable_Elements.Table
815 (The_Variable_Id).Next;
816 end loop;
817
818 end if;
819
820 if From_Project_Node_Tree.Incomplete_With then
821 if The_Variable_Id = No_Variable then
822 The_Variable := Nil_Variable_Value;
823 else
824 The_Variable :=
825 Shared.Variable_Elements.Table
826 (The_Variable_Id).Value;
827 end if;
828
829 else
830 pragma Assert (The_Variable_Id /= No_Variable,
831 "variable or attribute not found");
832
833 The_Variable :=
834 Shared.Variable_Elements.Table
835 (The_Variable_Id).Value;
836 end if;
837
838 else
839
840 -- It is an associative array attribute
841
842 declare
843 The_Array : Array_Id := No_Array;
844 The_Element : Array_Element_Id := No_Array_Element;
845 Array_Index : Name_Id := No_Name;
846
847 begin
848 if The_Package /= No_Package then
849 The_Array :=
850 Shared.Packages.Table (The_Package).Decl.Arrays;
851 else
852 The_Array := The_Project.Decl.Arrays;
853 end if;
854
855 while The_Array /= No_Array
856 and then Shared.Arrays.Table (The_Array).Name /=
857 The_Name
858 loop
859 The_Array := Shared.Arrays.Table (The_Array).Next;
860 end loop;
861
862 if The_Array /= No_Array then
863 The_Element :=
864 Shared.Arrays.Table (The_Array).Value;
865 Array_Index :=
866 Get_Attribute_Index
867 (From_Project_Node_Tree,
868 The_Current_Term,
869 Index);
870
871 while The_Element /= No_Array_Element
872 and then Shared.Array_Elements.Table
873 (The_Element).Index /= Array_Index
874 loop
875 The_Element :=
876 Shared.Array_Elements.Table (The_Element).Next;
877 end loop;
878
879 end if;
880
881 if The_Element /= No_Array_Element then
882 The_Variable :=
883 Shared.Array_Elements.Table (The_Element).Value;
884
885 else
886 if Expression_Kind_Of
887 (The_Current_Term, From_Project_Node_Tree) =
888 List
889 then
890 The_Variable :=
891 (Project => Project,
892 Kind => List,
893 Location => No_Location,
894 Default => True,
895 Values => Nil_String);
896 else
897 The_Variable :=
898 (Project => Project,
899 Kind => Single,
900 Location => No_Location,
901 Default => True,
902 Value => Empty_String,
903 Index => 0);
904 end if;
905 end if;
906 end;
907 end if;
908
909 -- Check the defaults
910
911 if Current_Term_Kind = N_Attribute_Reference then
912 declare
913 The_Default : constant Attribute_Default_Value :=
914 Default_Of
915 (The_Current_Term, From_Project_Node_Tree);
916
917 begin
918 -- Check the special value for 'Target when specified
919
920 if The_Default = Target_Value
921 and then Opt.Target_Origin = Specified
922 then
923 Name_Len := 0;
924 Add_Str_To_Name_Buffer (Opt.Target_Value.all);
925 The_Variable.Value := Name_Find;
926
927 -- Check the defaults
928
929 elsif The_Variable.Default then
930 case The_Variable.Kind is
931
932 when Undefined =>
933 null;
934
935 when Single =>
936 case The_Default is
937 when Read_Only_Value =>
938 null;
939
940 when Empty_Value =>
941 The_Variable.Value := Empty_String;
942
943 when Dot_Value =>
944 The_Variable.Value := Dot_String;
945
946 when Object_Dir_Value =>
947 From_Project_Node_Tree.Project_Nodes.Table
948 (The_Current_Term).Name :=
949 Snames.Name_Object_Dir;
950 From_Project_Node_Tree.Project_Nodes.Table
951 (The_Current_Term).Default :=
952 Dot_Value;
953 goto Object_Dir_Restart;
954
955 when Target_Value =>
956 if Opt.Target_Value = null then
957 The_Variable.Value := Empty_String;
958
959 else
960 Name_Len := 0;
961 Add_Str_To_Name_Buffer
962 (Opt.Target_Value.all);
963 The_Variable.Value := Name_Find;
964 end if;
965
966 when Runtime_Value =>
967 Get_Name_String (Index);
968 To_Lower (Name_Buffer (1 .. Name_Len));
969 The_Variable.Value :=
970 Runtime_Defaults.Get (Name_Find);
971 if The_Variable.Value = No_Name then
972 The_Variable.Value := Empty_String;
973 end if;
974
975 end case;
976
977 when List =>
978 case The_Default is
979 when Read_Only_Value =>
980 null;
981
982 when Empty_Value =>
983 The_Variable.Values := Nil_String;
984
985 when Dot_Value =>
986 The_Variable.Values :=
987 Shared.Dot_String_List;
988
989 when Object_Dir_Value |
990 Target_Value |
991 Runtime_Value =>
992 null;
993 end case;
994 end case;
995 end if;
996 end;
997 end if;
998
999 case Kind is
1000 when Undefined =>
1001
1002 -- Should never happen
1003
1004 pragma Assert (False, "undefined expression kind");
1005 null;
1006
1007 when Single =>
1008 case The_Variable.Kind is
1009
1010 when Undefined =>
1011 null;
1012
1013 when Single =>
1014 Add (Result.Value, The_Variable.Value);
1015
1016 when List =>
1017
1018 -- Should never happen
1019
1020 pragma Assert
1021 (False,
1022 "list cannot appear in single " &
1023 "string expression");
1024 null;
1025 end case;
1026
1027 when List =>
1028 case The_Variable.Kind is
1029
1030 when Undefined =>
1031 null;
1032
1033 when Single =>
1034 String_Element_Table.Increment_Last
1035 (Shared.String_Elements);
1036
1037 if Last = Nil_String then
1038
1039 -- This can happen in an expression such as
1040 -- () & Var
1041
1042 Result.Values :=
1043 String_Element_Table.Last
1044 (Shared.String_Elements);
1045
1046 else
1047 Shared.String_Elements.Table (Last).Next :=
1048 String_Element_Table.Last
1049 (Shared.String_Elements);
1050 end if;
1051
1052 Last :=
1053 String_Element_Table.Last
1054 (Shared.String_Elements);
1055
1056 Shared.String_Elements.Table (Last) :=
1057 (Value => The_Variable.Value,
1058 Display_Value => No_Name,
1059 Location => Location_Of
1060 (The_Current_Term,
1061 From_Project_Node_Tree),
1062 Flag => False,
1063 Next => Nil_String,
1064 Index => 0);
1065
1066 when List =>
1067
1068 declare
1069 The_List : String_List_Id :=
1070 The_Variable.Values;
1071
1072 begin
1073 while The_List /= Nil_String loop
1074 String_Element_Table.Increment_Last
1075 (Shared.String_Elements);
1076
1077 if Last = Nil_String then
1078 Result.Values :=
1079 String_Element_Table.Last
1080 (Shared.String_Elements);
1081
1082 else
1083 Shared.
1084 String_Elements.Table (Last).Next :=
1085 String_Element_Table.Last
1086 (Shared.String_Elements);
1087
1088 end if;
1089
1090 Last :=
1091 String_Element_Table.Last
1092 (Shared.String_Elements);
1093
1094 Shared.String_Elements.Table
1095 (Last) :=
1096 (Value =>
1097 Shared.String_Elements.Table
1098 (The_List).Value,
1099 Display_Value => No_Name,
1100 Location =>
1101 Location_Of
1102 (The_Current_Term,
1103 From_Project_Node_Tree),
1104 Flag => False,
1105 Next => Nil_String,
1106 Index => 0);
1107
1108 The_List := Shared.String_Elements.Table
1109 (The_List).Next;
1110 end loop;
1111 end;
1112 end case;
1113 end case;
1114 end;
1115
1116 when N_External_Value =>
1117 Get_Name_String
1118 (String_Value_Of
1119 (External_Reference_Of
1120 (The_Current_Term, From_Project_Node_Tree),
1121 From_Project_Node_Tree));
1122
1123 declare
1124 Name : constant Name_Id := Name_Find;
1125 Default : Name_Id := No_Name;
1126 Value : Name_Id := No_Name;
1127 Ext_List : Boolean := False;
1128 Str_List : String_List_Access := null;
1129 Def_Var : Variable_Value;
1130
1131 Default_Node : constant Project_Node_Id :=
1132 External_Default_Of
1133 (The_Current_Term,
1134 From_Project_Node_Tree);
1135
1136 begin
1137 -- If there is a default value for the external reference,
1138 -- get its value.
1139
1140 if Present (Default_Node) then
1141 Def_Var := Expression
1142 (Project => Project,
1143 Shared => Shared,
1144 From_Project_Node => From_Project_Node,
1145 From_Project_Node_Tree => From_Project_Node_Tree,
1146 Env => Env,
1147 Pkg => Pkg,
1148 First_Term =>
1149 Tree.First_Term
1150 (Default_Node, From_Project_Node_Tree),
1151 Kind => Single);
1152
1153 if Def_Var /= Nil_Variable_Value then
1154 Default := Def_Var.Value;
1155 end if;
1156 end if;
1157
1158 Ext_List := Expression_Kind_Of
1159 (The_Current_Term,
1160 From_Project_Node_Tree) = List;
1161
1162 if Ext_List then
1163 Value := Prj.Ext.Value_Of (Env.External, Name, No_Name);
1164
1165 if Value /= No_Name then
1166 declare
1167 Sep : constant String :=
1168 Get_Name_String (Default);
1169 First : Positive := 1;
1170 Lst : Natural;
1171 Done : Boolean := False;
1172 Nmb : Natural;
1173
1174 begin
1175 Get_Name_String (Value);
1176
1177 if Name_Len = 0
1178 or else Sep'Length = 0
1179 or else Name_Buffer (1 .. Name_Len) = Sep
1180 then
1181 Done := True;
1182 end if;
1183
1184 if not Done and then Name_Len < Sep'Length then
1185 Str_List :=
1186 new String_List'
1187 (1 => new String'
1188 (Name_Buffer (1 .. Name_Len)));
1189 Done := True;
1190 end if;
1191
1192 if not Done then
1193 if Name_Buffer (1 .. Sep'Length) = Sep then
1194 First := Sep'Length + 1;
1195 end if;
1196
1197 if Name_Len - First + 1 >= Sep'Length
1198 and then
1199 Name_Buffer (Name_Len - Sep'Length + 1 ..
1200 Name_Len) = Sep
1201 then
1202 Name_Len := Name_Len - Sep'Length;
1203 end if;
1204
1205 if Name_Len = 0 then
1206 Str_List :=
1207 new String_List'(1 => new String'(""));
1208 Done := True;
1209 end if;
1210 end if;
1211
1212 if not Done then
1213
1214 -- Count the number of strings
1215
1216 declare
1217 Saved : constant Positive := First;
1218
1219 begin
1220 Nmb := 1;
1221 loop
1222 Lst :=
1223 Index
1224 (Source =>
1225 Name_Buffer (First .. Name_Len),
1226 Pattern => Sep);
1227 exit when Lst = 0;
1228 Nmb := Nmb + 1;
1229 First := Lst + Sep'Length;
1230 end loop;
1231
1232 First := Saved;
1233 end;
1234
1235 Str_List := new String_List (1 .. Nmb);
1236
1237 -- Populate the string list
1238
1239 Nmb := 1;
1240 loop
1241 Lst :=
1242 Index
1243 (Source =>
1244 Name_Buffer (First .. Name_Len),
1245 Pattern => Sep);
1246
1247 if Lst = 0 then
1248 Str_List (Nmb) :=
1249 new String'
1250 (Name_Buffer (First .. Name_Len));
1251 exit;
1252
1253 else
1254 Str_List (Nmb) :=
1255 new String'
1256 (Name_Buffer (First .. Lst - 1));
1257 Nmb := Nmb + 1;
1258 First := Lst + Sep'Length;
1259 end if;
1260 end loop;
1261 end if;
1262 end;
1263 end if;
1264
1265 else
1266 -- Get the value
1267
1268 Value := Prj.Ext.Value_Of (Env.External, Name, Default);
1269
1270 if Value = No_Name then
1271 if not Quiet_Output then
1272 Error_Msg
1273 (Env.Flags, "?undefined external reference",
1274 Location_Of
1275 (The_Current_Term, From_Project_Node_Tree),
1276 Project);
1277 end if;
1278
1279 Value := Empty_String;
1280 end if;
1281 end if;
1282
1283 case Kind is
1284
1285 when Undefined =>
1286 null;
1287
1288 when Single =>
1289 if Ext_List then
1290 null; -- error
1291
1292 else
1293 Add (Result.Value, Value);
1294 end if;
1295
1296 when List =>
1297 if not Ext_List or else Str_List /= null then
1298 String_Element_Table.Increment_Last
1299 (Shared.String_Elements);
1300
1301 if Last = Nil_String then
1302 Result.Values :=
1303 String_Element_Table.Last
1304 (Shared.String_Elements);
1305
1306 else
1307 Shared.String_Elements.Table (Last).Next
1308 := String_Element_Table.Last
1309 (Shared.String_Elements);
1310 end if;
1311
1312 Last := String_Element_Table.Last
1313 (Shared.String_Elements);
1314
1315 if Ext_List then
1316 for Ind in Str_List'Range loop
1317 Name_Len := 0;
1318 Add_Str_To_Name_Buffer (Str_List (Ind).all);
1319 Value := Name_Find;
1320 Shared.String_Elements.Table (Last) :=
1321 (Value => Value,
1322 Display_Value => No_Name,
1323 Location =>
1324 Location_Of
1325 (The_Current_Term,
1326 From_Project_Node_Tree),
1327 Flag => False,
1328 Next => Nil_String,
1329 Index => 0);
1330
1331 if Ind /= Str_List'Last then
1332 String_Element_Table.Increment_Last
1333 (Shared.String_Elements);
1334 Shared.String_Elements.Table (Last).Next :=
1335 String_Element_Table.Last
1336 (Shared.String_Elements);
1337 Last := String_Element_Table.Last
1338 (Shared.String_Elements);
1339 end if;
1340 end loop;
1341
1342 else
1343 Shared.String_Elements.Table (Last) :=
1344 (Value => Value,
1345 Display_Value => No_Name,
1346 Location =>
1347 Location_Of
1348 (The_Current_Term,
1349 From_Project_Node_Tree),
1350 Flag => False,
1351 Next => Nil_String,
1352 Index => 0);
1353 end if;
1354 end if;
1355 end case;
1356 end;
1357
1358 when others =>
1359
1360 -- Should never happen
1361
1362 pragma Assert
1363 (False,
1364 "illegal node kind in an expression");
1365 raise Program_Error;
1366
1367 end case;
1368 end if;
1369
1370 The_Term := Next_Term (The_Term, From_Project_Node_Tree);
1371 end loop;
1372
1373 return Result;
1374 end Expression;
1375
1376 ---------------------------------------
1377 -- Imported_Or_Extended_Project_From --
1378 ---------------------------------------
1379
1380 function Imported_Or_Extended_Project_From
1381 (Project : Project_Id;
1382 With_Name : Name_Id;
1383 No_Extending : Boolean := False) return Project_Id
1384 is
1385 List : Project_List;
1386 Result : Project_Id;
1387 Temp_Result : Project_Id;
1388
1389 begin
1390 -- First check if it is the name of an extended project
1391
1392 Result := Project.Extends;
1393 while Result /= No_Project loop
1394 if Result.Name = With_Name then
1395 return Result;
1396 else
1397 Result := Result.Extends;
1398 end if;
1399 end loop;
1400
1401 -- Then check the name of each imported project
1402
1403 Temp_Result := No_Project;
1404 List := Project.Imported_Projects;
1405 while List /= null loop
1406 Result := List.Project;
1407
1408 -- If the project is directly imported, then returns its ID
1409
1410 if Result.Name = With_Name then
1411 return Result;
1412 end if;
1413
1414 -- If a project extending the project is imported, then keep this
1415 -- extending project as a possibility. It will be the returned ID
1416 -- if the project is not imported directly.
1417
1418 declare
1419 Proj : Project_Id;
1420
1421 begin
1422 Proj := Result.Extends;
1423 while Proj /= No_Project loop
1424 if Proj.Name = With_Name then
1425 if No_Extending then
1426 Temp_Result := Proj;
1427 else
1428 Temp_Result := Result;
1429 end if;
1430
1431 exit;
1432 end if;
1433
1434 Proj := Proj.Extends;
1435 end loop;
1436 end;
1437
1438 List := List.Next;
1439 end loop;
1440
1441 pragma Assert (Temp_Result /= No_Project, "project not found");
1442 return Temp_Result;
1443 end Imported_Or_Extended_Project_From;
1444
1445 ------------------
1446 -- Package_From --
1447 ------------------
1448
1449 function Package_From
1450 (Project : Project_Id;
1451 Shared : Shared_Project_Tree_Data_Access;
1452 With_Name : Name_Id) return Package_Id
1453 is
1454 Result : Package_Id := Project.Decl.Packages;
1455
1456 begin
1457 -- Check the name of each existing package of Project
1458
1459 while Result /= No_Package
1460 and then Shared.Packages.Table (Result).Name /= With_Name
1461 loop
1462 Result := Shared.Packages.Table (Result).Next;
1463 end loop;
1464
1465 if Result = No_Package then
1466
1467 -- Should never happen
1468
1469 Write_Line
1470 ("package """ & Get_Name_String (With_Name) & """ not found");
1471 raise Program_Error;
1472
1473 else
1474 return Result;
1475 end if;
1476 end Package_From;
1477
1478 -------------
1479 -- Process --
1480 -------------
1481
1482 procedure Process
1483 (In_Tree : Project_Tree_Ref;
1484 Project : out Project_Id;
1485 Packages_To_Check : String_List_Access;
1486 Success : out Boolean;
1487 From_Project_Node : Project_Node_Id;
1488 From_Project_Node_Tree : Project_Node_Tree_Ref;
1489 Env : in out Prj.Tree.Environment;
1490 Reset_Tree : Boolean := True;
1491 On_New_Tree_Loaded : Tree_Loaded_Callback := null)
1492 is
1493 begin
1494 Process_Project_Tree_Phase_1
1495 (In_Tree => In_Tree,
1496 Project => Project,
1497 Success => Success,
1498 From_Project_Node => From_Project_Node,
1499 From_Project_Node_Tree => From_Project_Node_Tree,
1500 Env => Env,
1501 Packages_To_Check => Packages_To_Check,
1502 Reset_Tree => Reset_Tree,
1503 On_New_Tree_Loaded => On_New_Tree_Loaded);
1504
1505 if Project_Qualifier_Of
1506 (From_Project_Node, From_Project_Node_Tree) /= Configuration
1507 then
1508 Process_Project_Tree_Phase_2
1509 (In_Tree => In_Tree,
1510 Project => Project,
1511 Success => Success,
1512 From_Project_Node => From_Project_Node,
1513 From_Project_Node_Tree => From_Project_Node_Tree,
1514 Env => Env);
1515 end if;
1516 end Process;
1517
1518 -------------------------------
1519 -- Process_Declarative_Items --
1520 -------------------------------
1521
1522 procedure Process_Declarative_Items
1523 (Project : Project_Id;
1524 In_Tree : Project_Tree_Ref;
1525 From_Project_Node : Project_Node_Id;
1526 Node_Tree : Project_Node_Tree_Ref;
1527 Env : Prj.Tree.Environment;
1528 Pkg : Package_Id;
1529 Item : Project_Node_Id;
1530 Child_Env : in out Prj.Tree.Environment)
1531 is
1532 Shared : constant Shared_Project_Tree_Data_Access := In_Tree.Shared;
1533
1534 procedure Check_Or_Set_Typed_Variable
1535 (Value : in out Variable_Value;
1536 Declaration : Project_Node_Id);
1537 -- Check whether Value is valid for this typed variable declaration. If
1538 -- it is an error, the behavior depends on the flags: either an error is
1539 -- reported, or a warning, or nothing. In the last two cases, the value
1540 -- of the variable is set to a valid value, replacing Value.
1541
1542 procedure Process_Package_Declaration
1543 (Current_Item : Project_Node_Id);
1544 procedure Process_Attribute_Declaration
1545 (Current : Project_Node_Id);
1546 procedure Process_Case_Construction
1547 (Current_Item : Project_Node_Id);
1548 procedure Process_Associative_Array
1549 (Current_Item : Project_Node_Id);
1550 procedure Process_Expression
1551 (Current : Project_Node_Id);
1552 procedure Process_Expression_For_Associative_Array
1553 (Current : Project_Node_Id;
1554 New_Value : Variable_Value);
1555 procedure Process_Expression_Variable_Decl
1556 (Current_Item : Project_Node_Id;
1557 New_Value : Variable_Value);
1558 -- Process the various declarative items
1559
1560 ---------------------------------
1561 -- Check_Or_Set_Typed_Variable --
1562 ---------------------------------
1563
1564 procedure Check_Or_Set_Typed_Variable
1565 (Value : in out Variable_Value;
1566 Declaration : Project_Node_Id)
1567 is
1568 Loc : constant Source_Ptr := Location_Of (Declaration, Node_Tree);
1569
1570 Reset_Value : Boolean := False;
1571 Current_String : Project_Node_Id;
1572
1573 begin
1574 -- Report an error for an empty string
1575
1576 if Value.Value = Empty_String then
1577 Error_Msg_Name_1 := Name_Of (Declaration, Node_Tree);
1578
1579 case Env.Flags.Allow_Invalid_External is
1580 when Error =>
1581 Error_Msg
1582 (Env.Flags, "no value defined for %%", Loc, Project);
1583 when Warning =>
1584 Reset_Value := True;
1585 Error_Msg
1586 (Env.Flags, "?no value defined for %%", Loc, Project);
1587 when Silent =>
1588 Reset_Value := True;
1589 end case;
1590
1591 else
1592 -- Loop through all the valid strings for the
1593 -- string type and compare to the string value.
1594
1595 Current_String :=
1596 First_Literal_String
1597 (String_Type_Of (Declaration, Node_Tree), Node_Tree);
1598
1599 while Present (Current_String)
1600 and then
1601 String_Value_Of (Current_String, Node_Tree) /= Value.Value
1602 loop
1603 Current_String :=
1604 Next_Literal_String (Current_String, Node_Tree);
1605 end loop;
1606
1607 -- Report error if string value is not one for the string type
1608
1609 if No (Current_String) then
1610 Error_Msg_Name_1 := Value.Value;
1611 Error_Msg_Name_2 := Name_Of (Declaration, Node_Tree);
1612
1613 case Env.Flags.Allow_Invalid_External is
1614 when Error =>
1615 Error_Msg
1616 (Env.Flags, "value %% is illegal for typed string %%",
1617 Loc, Project);
1618
1619 when Warning =>
1620 Error_Msg
1621 (Env.Flags, "?value %% is illegal for typed string %%",
1622 Loc, Project);
1623 Reset_Value := True;
1624
1625 when Silent =>
1626 Reset_Value := True;
1627 end case;
1628 end if;
1629 end if;
1630
1631 if Reset_Value then
1632 Current_String :=
1633 First_Literal_String
1634 (String_Type_Of (Declaration, Node_Tree), Node_Tree);
1635 Value.Value := String_Value_Of (Current_String, Node_Tree);
1636 end if;
1637 end Check_Or_Set_Typed_Variable;
1638
1639 ---------------------------------
1640 -- Process_Package_Declaration --
1641 ---------------------------------
1642
1643 procedure Process_Package_Declaration
1644 (Current_Item : Project_Node_Id)
1645 is
1646 begin
1647 -- Do not process a package declaration that should be ignored
1648
1649 if Expression_Kind_Of (Current_Item, Node_Tree) /= Ignored then
1650
1651 -- Create the new package
1652
1653 Package_Table.Increment_Last (Shared.Packages);
1654
1655 declare
1656 New_Pkg : constant Package_Id :=
1657 Package_Table.Last (Shared.Packages);
1658 The_New_Package : Package_Element;
1659
1660 Project_Of_Renamed_Package : constant Project_Node_Id :=
1661 Project_Of_Renamed_Package_Of
1662 (Current_Item, Node_Tree);
1663
1664 begin
1665 -- Set the name of the new package
1666
1667 The_New_Package.Name := Name_Of (Current_Item, Node_Tree);
1668
1669 -- Insert the new package in the appropriate list
1670
1671 if Pkg /= No_Package then
1672 The_New_Package.Next :=
1673 Shared.Packages.Table (Pkg).Decl.Packages;
1674 Shared.Packages.Table (Pkg).Decl.Packages := New_Pkg;
1675
1676 else
1677 The_New_Package.Next := Project.Decl.Packages;
1678 Project.Decl.Packages := New_Pkg;
1679 end if;
1680
1681 Shared.Packages.Table (New_Pkg) := The_New_Package;
1682
1683 if Present (Project_Of_Renamed_Package) then
1684
1685 -- Renamed or extending package
1686
1687 declare
1688 Project_Name : constant Name_Id :=
1689 Name_Of (Project_Of_Renamed_Package,
1690 Node_Tree);
1691
1692 Renamed_Project : constant Project_Id :=
1693 Imported_Or_Extended_Project_From
1694 (Project, Project_Name);
1695
1696 Renamed_Package : constant Package_Id :=
1697 Package_From
1698 (Renamed_Project, Shared,
1699 Name_Of (Current_Item, Node_Tree));
1700
1701 begin
1702 -- For a renamed package, copy the declarations of the
1703 -- renamed package, but set all the locations to the
1704 -- location of the package name in the renaming
1705 -- declaration.
1706
1707 Copy_Package_Declarations
1708 (From => Shared.Packages.Table
1709 (Renamed_Package).Decl,
1710 To => Shared.Packages.Table (New_Pkg).Decl,
1711 New_Loc => Location_Of (Current_Item, Node_Tree),
1712 Restricted => False,
1713 Shared => Shared);
1714 end;
1715
1716 else
1717 -- Set the default values of the attributes
1718
1719 Add_Attributes
1720 (Project,
1721 Project.Name,
1722 Name_Id (Project.Directory.Display_Name),
1723 Shared,
1724 Shared.Packages.Table (New_Pkg).Decl,
1725 First_Attribute_Of
1726 (Package_Id_Of (Current_Item, Node_Tree)),
1727 Project_Level => False);
1728 end if;
1729
1730 -- Process declarative items (nothing to do when the package is
1731 -- renaming, as the first declarative item is null).
1732
1733 Process_Declarative_Items
1734 (Project => Project,
1735 In_Tree => In_Tree,
1736 From_Project_Node => From_Project_Node,
1737 Node_Tree => Node_Tree,
1738 Env => Env,
1739 Pkg => New_Pkg,
1740 Item =>
1741 First_Declarative_Item_Of (Current_Item, Node_Tree),
1742 Child_Env => Child_Env);
1743 end;
1744 end if;
1745 end Process_Package_Declaration;
1746
1747 -------------------------------
1748 -- Process_Associative_Array --
1749 -------------------------------
1750
1751 procedure Process_Associative_Array
1752 (Current_Item : Project_Node_Id)
1753 is
1754 Current_Item_Name : constant Name_Id :=
1755 Name_Of (Current_Item, Node_Tree);
1756 -- The name of the attribute
1757
1758 Current_Location : constant Source_Ptr :=
1759 Location_Of (Current_Item, Node_Tree);
1760
1761 New_Array : Array_Id;
1762 -- The new associative array created
1763
1764 Orig_Array : Array_Id;
1765 -- The associative array value
1766
1767 Orig_Project_Name : Name_Id := No_Name;
1768 -- The name of the project where the associative array
1769 -- value is.
1770
1771 Orig_Project : Project_Id := No_Project;
1772 -- The id of the project where the associative array
1773 -- value is.
1774
1775 Orig_Package_Name : Name_Id := No_Name;
1776 -- The name of the package, if any, where the associative array value
1777 -- is located.
1778
1779 Orig_Package : Package_Id := No_Package;
1780 -- The id of the package, if any, where the associative array value
1781 -- is located.
1782
1783 New_Element : Array_Element_Id := No_Array_Element;
1784 -- Id of a new array element created
1785
1786 Prev_Element : Array_Element_Id := No_Array_Element;
1787 -- Last new element id created
1788
1789 Orig_Element : Array_Element_Id := No_Array_Element;
1790 -- Current array element in original associative array
1791
1792 Next_Element : Array_Element_Id := No_Array_Element;
1793 -- Id of the array element that follows the new element. This is not
1794 -- always nil, because values for the associative array attribute may
1795 -- already have been declared, and the array elements declared are
1796 -- reused.
1797
1798 Prj : Project_List;
1799
1800 begin
1801 -- First find if the associative array attribute already has elements
1802 -- declared.
1803
1804 if Pkg /= No_Package then
1805 New_Array := Shared.Packages.Table (Pkg).Decl.Arrays;
1806 else
1807 New_Array := Project.Decl.Arrays;
1808 end if;
1809
1810 while New_Array /= No_Array
1811 and then Shared.Arrays.Table (New_Array).Name /= Current_Item_Name
1812 loop
1813 New_Array := Shared.Arrays.Table (New_Array).Next;
1814 end loop;
1815
1816 -- If the attribute has never been declared add new entry in the
1817 -- arrays of the project/package and link it.
1818
1819 if New_Array = No_Array then
1820 Array_Table.Increment_Last (Shared.Arrays);
1821 New_Array := Array_Table.Last (Shared.Arrays);
1822
1823 if Pkg /= No_Package then
1824 Shared.Arrays.Table (New_Array) :=
1825 (Name => Current_Item_Name,
1826 Location => Current_Location,
1827 Value => No_Array_Element,
1828 Next => Shared.Packages.Table (Pkg).Decl.Arrays);
1829
1830 Shared.Packages.Table (Pkg).Decl.Arrays := New_Array;
1831
1832 else
1833 Shared.Arrays.Table (New_Array) :=
1834 (Name => Current_Item_Name,
1835 Location => Current_Location,
1836 Value => No_Array_Element,
1837 Next => Project.Decl.Arrays);
1838
1839 Project.Decl.Arrays := New_Array;
1840 end if;
1841 end if;
1842
1843 -- Find the project where the value is declared
1844
1845 Orig_Project_Name :=
1846 Name_Of
1847 (Associative_Project_Of (Current_Item, Node_Tree), Node_Tree);
1848
1849 Prj := In_Tree.Projects;
1850 while Prj /= null loop
1851 if Prj.Project.Name = Orig_Project_Name then
1852 Orig_Project := Prj.Project;
1853 exit;
1854 end if;
1855 Prj := Prj.Next;
1856 end loop;
1857
1858 pragma Assert (Orig_Project /= No_Project,
1859 "original project not found");
1860
1861 if No (Associative_Package_Of (Current_Item, Node_Tree)) then
1862 Orig_Array := Orig_Project.Decl.Arrays;
1863
1864 else
1865 -- If in a package, find the package where the value is declared
1866
1867 Orig_Package_Name :=
1868 Name_Of
1869 (Associative_Package_Of (Current_Item, Node_Tree), Node_Tree);
1870
1871 Orig_Package := Orig_Project.Decl.Packages;
1872 pragma Assert (Orig_Package /= No_Package,
1873 "original package not found");
1874
1875 while Shared.Packages.Table
1876 (Orig_Package).Name /= Orig_Package_Name
1877 loop
1878 Orig_Package := Shared.Packages.Table (Orig_Package).Next;
1879 pragma Assert (Orig_Package /= No_Package,
1880 "original package not found");
1881 end loop;
1882
1883 Orig_Array := Shared.Packages.Table (Orig_Package).Decl.Arrays;
1884 end if;
1885
1886 -- Now look for the array
1887
1888 while Orig_Array /= No_Array
1889 and then Shared.Arrays.Table (Orig_Array).Name /= Current_Item_Name
1890 loop
1891 Orig_Array := Shared.Arrays.Table (Orig_Array).Next;
1892 end loop;
1893
1894 if Orig_Array = No_Array then
1895 Error_Msg
1896 (Env.Flags,
1897 "associative array value not found",
1898 Location_Of (Current_Item, Node_Tree),
1899 Project);
1900
1901 else
1902 Orig_Element := Shared.Arrays.Table (Orig_Array).Value;
1903
1904 -- Copy each array element
1905
1906 while Orig_Element /= No_Array_Element loop
1907
1908 -- Case of first element
1909
1910 if Prev_Element = No_Array_Element then
1911
1912 -- And there is no array element declared yet, create a new
1913 -- first array element.
1914
1915 if Shared.Arrays.Table (New_Array).Value =
1916 No_Array_Element
1917 then
1918 Array_Element_Table.Increment_Last
1919 (Shared.Array_Elements);
1920 New_Element := Array_Element_Table.Last
1921 (Shared.Array_Elements);
1922 Shared.Arrays.Table (New_Array).Value := New_Element;
1923 Next_Element := No_Array_Element;
1924
1925 -- Otherwise, the new element is the first
1926
1927 else
1928 New_Element := Shared.Arrays.Table (New_Array).Value;
1929 Next_Element :=
1930 Shared.Array_Elements.Table (New_Element).Next;
1931 end if;
1932
1933 -- Otherwise, reuse an existing element, or create
1934 -- one if necessary.
1935
1936 else
1937 Next_Element :=
1938 Shared.Array_Elements.Table (Prev_Element).Next;
1939
1940 if Next_Element = No_Array_Element then
1941 Array_Element_Table.Increment_Last
1942 (Shared.Array_Elements);
1943 New_Element := Array_Element_Table.Last
1944 (Shared.Array_Elements);
1945 Shared.Array_Elements.Table (Prev_Element).Next :=
1946 New_Element;
1947
1948 else
1949 New_Element := Next_Element;
1950 Next_Element :=
1951 Shared.Array_Elements.Table (New_Element).Next;
1952 end if;
1953 end if;
1954
1955 -- Copy the value of the element
1956
1957 Shared.Array_Elements.Table (New_Element) :=
1958 Shared.Array_Elements.Table (Orig_Element);
1959 Shared.Array_Elements.Table (New_Element).Value.Project
1960 := Project;
1961
1962 -- Adjust the Next link
1963
1964 Shared.Array_Elements.Table (New_Element).Next := Next_Element;
1965
1966 -- Adjust the previous id for the next element
1967
1968 Prev_Element := New_Element;
1969
1970 -- Go to the next element in the original array
1971
1972 Orig_Element := Shared.Array_Elements.Table (Orig_Element).Next;
1973 end loop;
1974
1975 -- Make sure that the array ends here, in case there previously a
1976 -- greater number of elements.
1977
1978 Shared.Array_Elements.Table (New_Element).Next := No_Array_Element;
1979 end if;
1980 end Process_Associative_Array;
1981
1982 ----------------------------------------------
1983 -- Process_Expression_For_Associative_Array --
1984 ----------------------------------------------
1985
1986 procedure Process_Expression_For_Associative_Array
1987 (Current : Project_Node_Id;
1988 New_Value : Variable_Value)
1989 is
1990 Name : constant Name_Id := Name_Of (Current, Node_Tree);
1991 Current_Location : constant Source_Ptr :=
1992 Location_Of (Current, Node_Tree);
1993
1994 Index_Name : Name_Id :=
1995 Associative_Array_Index_Of (Current, Node_Tree);
1996
1997 Source_Index : constant Int :=
1998 Source_Index_Of (Current, Node_Tree);
1999
2000 The_Array : Array_Id;
2001 Elem : Array_Element_Id := No_Array_Element;
2002
2003 begin
2004 if Index_Name /= All_Other_Names then
2005 Index_Name := Get_Attribute_Index (Node_Tree, Current, Index_Name);
2006 end if;
2007
2008 -- Look for the array in the appropriate list
2009
2010 if Pkg /= No_Package then
2011 The_Array := Shared.Packages.Table (Pkg).Decl.Arrays;
2012 else
2013 The_Array := Project.Decl.Arrays;
2014 end if;
2015
2016 while The_Array /= No_Array
2017 and then Shared.Arrays.Table (The_Array).Name /= Name
2018 loop
2019 The_Array := Shared.Arrays.Table (The_Array).Next;
2020 end loop;
2021
2022 -- If the array cannot be found, create a new entry in the list.
2023 -- As The_Array_Element is initialized to No_Array_Element, a new
2024 -- element will be created automatically later
2025
2026 if The_Array = No_Array then
2027 Array_Table.Increment_Last (Shared.Arrays);
2028 The_Array := Array_Table.Last (Shared.Arrays);
2029
2030 if Pkg /= No_Package then
2031 Shared.Arrays.Table (The_Array) :=
2032 (Name => Name,
2033 Location => Current_Location,
2034 Value => No_Array_Element,
2035 Next => Shared.Packages.Table (Pkg).Decl.Arrays);
2036
2037 Shared.Packages.Table (Pkg).Decl.Arrays := The_Array;
2038
2039 else
2040 Shared.Arrays.Table (The_Array) :=
2041 (Name => Name,
2042 Location => Current_Location,
2043 Value => No_Array_Element,
2044 Next => Project.Decl.Arrays);
2045
2046 Project.Decl.Arrays := The_Array;
2047 end if;
2048
2049 else
2050 Elem := Shared.Arrays.Table (The_Array).Value;
2051 end if;
2052
2053 -- Look in the list, if any, to find an element with the same index
2054 -- and same source index.
2055
2056 while Elem /= No_Array_Element
2057 and then
2058 (Shared.Array_Elements.Table (Elem).Index /= Index_Name
2059 or else
2060 Shared.Array_Elements.Table (Elem).Src_Index /= Source_Index)
2061 loop
2062 Elem := Shared.Array_Elements.Table (Elem).Next;
2063 end loop;
2064
2065 -- If no such element were found, create a new one
2066 -- and insert it in the element list, with the
2067 -- proper value.
2068
2069 if Elem = No_Array_Element then
2070 Array_Element_Table.Increment_Last (Shared.Array_Elements);
2071 Elem := Array_Element_Table.Last (Shared.Array_Elements);
2072
2073 Shared.Array_Elements.Table
2074 (Elem) :=
2075 (Index => Index_Name,
2076 Restricted => False,
2077 Src_Index => Source_Index,
2078 Index_Case_Sensitive =>
2079 not Case_Insensitive (Current, Node_Tree),
2080 Value => New_Value,
2081 Next => Shared.Arrays.Table (The_Array).Value);
2082
2083 Shared.Arrays.Table (The_Array).Value := Elem;
2084
2085 else
2086 -- An element with the same index already exists, just replace its
2087 -- value with the new one.
2088
2089 Shared.Array_Elements.Table (Elem).Value := New_Value;
2090 end if;
2091
2092 if Name = Snames.Name_External then
2093 if In_Tree.Is_Root_Tree then
2094 Add (Child_Env.External,
2095 External_Name => Get_Name_String (Index_Name),
2096 Value => Get_Name_String (New_Value.Value),
2097 Source => From_External_Attribute);
2098 Add (Env.External,
2099 External_Name => Get_Name_String (Index_Name),
2100 Value => Get_Name_String (New_Value.Value),
2101 Source => From_External_Attribute,
2102 Silent => True);
2103 else
2104 if Current_Verbosity = High then
2105 Debug_Output
2106 ("'for External' has no effect except in root aggregate ("
2107 & Get_Name_String (Index_Name) & ")", New_Value.Value);
2108 end if;
2109 end if;
2110 end if;
2111 end Process_Expression_For_Associative_Array;
2112
2113 --------------------------------------
2114 -- Process_Expression_Variable_Decl --
2115 --------------------------------------
2116
2117 procedure Process_Expression_Variable_Decl
2118 (Current_Item : Project_Node_Id;
2119 New_Value : Variable_Value)
2120 is
2121 Name : constant Name_Id := Name_Of (Current_Item, Node_Tree);
2122
2123 Is_Attribute : constant Boolean :=
2124 Kind_Of (Current_Item, Node_Tree) =
2125 N_Attribute_Declaration;
2126
2127 Var : Variable_Id := No_Variable;
2128
2129 begin
2130 -- First, find the list where to find the variable or attribute
2131
2132 if Is_Attribute then
2133 if Pkg /= No_Package then
2134 Var := Shared.Packages.Table (Pkg).Decl.Attributes;
2135 else
2136 Var := Project.Decl.Attributes;
2137 end if;
2138
2139 else
2140 if Pkg /= No_Package then
2141 Var := Shared.Packages.Table (Pkg).Decl.Variables;
2142 else
2143 Var := Project.Decl.Variables;
2144 end if;
2145 end if;
2146
2147 -- Loop through the list, to find if it has already been declared
2148
2149 while Var /= No_Variable
2150 and then Shared.Variable_Elements.Table (Var).Name /= Name
2151 loop
2152 Var := Shared.Variable_Elements.Table (Var).Next;
2153 end loop;
2154
2155 -- If it has not been declared, create a new entry in the list
2156
2157 if Var = No_Variable then
2158
2159 -- All single string attribute should already have been declared
2160 -- with a default empty string value.
2161
2162 pragma Assert
2163 (not Is_Attribute,
2164 "illegal attribute declaration for " & Get_Name_String (Name));
2165
2166 Variable_Element_Table.Increment_Last (Shared.Variable_Elements);
2167 Var := Variable_Element_Table.Last (Shared.Variable_Elements);
2168
2169 -- Put the new variable in the appropriate list
2170
2171 if Pkg /= No_Package then
2172 Shared.Variable_Elements.Table (Var) :=
2173 (Next => Shared.Packages.Table (Pkg).Decl.Variables,
2174 Name => Name,
2175 Value => New_Value);
2176 Shared.Packages.Table (Pkg).Decl.Variables := Var;
2177
2178 else
2179 Shared.Variable_Elements.Table (Var) :=
2180 (Next => Project.Decl.Variables,
2181 Name => Name,
2182 Value => New_Value);
2183 Project.Decl.Variables := Var;
2184 end if;
2185
2186 -- If the variable/attribute has already been declared, just
2187 -- change the value.
2188
2189 else
2190 Shared.Variable_Elements.Table (Var).Value := New_Value;
2191 end if;
2192
2193 if Is_Attribute and then Name = Snames.Name_Project_Path then
2194 if In_Tree.Is_Root_Tree then
2195 declare
2196 package Name_Ids is
2197 new Ada.Containers.Vectors (Positive, Name_Id);
2198 Val : String_List_Id := New_Value.Values;
2199 List : Name_Ids.Vector;
2200 begin
2201 -- Get all values
2202
2203 while Val /= Nil_String loop
2204 List.Prepend
2205 (Shared.String_Elements.Table (Val).Value);
2206 Val := Shared.String_Elements.Table (Val).Next;
2207 end loop;
2208
2209 -- Prepend them in the order found in the attribute
2210
2211 for K in Positive range 1 .. Positive (List.Length) loop
2212 Prj.Env.Add_Directories
2213 (Child_Env.Project_Path,
2214 Normalize_Pathname
2215 (Name => Get_Name_String
2216 (List.Element (K)),
2217 Directory => Get_Name_String
2218 (Project.Directory.Display_Name)),
2219 Prepend => True);
2220 end loop;
2221 end;
2222
2223 else
2224 if Current_Verbosity = High then
2225 Debug_Output
2226 ("'for Project_Path' has no effect except in"
2227 & " root aggregate");
2228 end if;
2229 end if;
2230 end if;
2231 end Process_Expression_Variable_Decl;
2232
2233 ------------------------
2234 -- Process_Expression --
2235 ------------------------
2236
2237 procedure Process_Expression (Current : Project_Node_Id) is
2238 New_Value : Variable_Value :=
2239 Expression
2240 (Project => Project,
2241 Shared => Shared,
2242 From_Project_Node => From_Project_Node,
2243 From_Project_Node_Tree => Node_Tree,
2244 Env => Env,
2245 Pkg => Pkg,
2246 First_Term =>
2247 Tree.First_Term
2248 (Expression_Of (Current, Node_Tree), Node_Tree),
2249 Kind =>
2250 Expression_Kind_Of (Current, Node_Tree));
2251
2252 begin
2253 -- Process a typed variable declaration
2254
2255 if Kind_Of (Current, Node_Tree) = N_Typed_Variable_Declaration then
2256 Check_Or_Set_Typed_Variable (New_Value, Current);
2257 end if;
2258
2259 if Kind_Of (Current, Node_Tree) /= N_Attribute_Declaration
2260 or else Associative_Array_Index_Of (Current, Node_Tree) = No_Name
2261 then
2262 Process_Expression_Variable_Decl (Current, New_Value);
2263 else
2264 Process_Expression_For_Associative_Array (Current, New_Value);
2265 end if;
2266 end Process_Expression;
2267
2268 -----------------------------------
2269 -- Process_Attribute_Declaration --
2270 -----------------------------------
2271
2272 procedure Process_Attribute_Declaration (Current : Project_Node_Id) is
2273 begin
2274 if Expression_Of (Current, Node_Tree) = Empty_Node then
2275 Process_Associative_Array (Current);
2276 else
2277 Process_Expression (Current);
2278 end if;
2279 end Process_Attribute_Declaration;
2280
2281 -------------------------------
2282 -- Process_Case_Construction --
2283 -------------------------------
2284
2285 procedure Process_Case_Construction
2286 (Current_Item : Project_Node_Id)
2287 is
2288 The_Project : Project_Id := Project;
2289 -- The id of the project of the case variable
2290
2291 The_Package : Package_Id := Pkg;
2292 -- The id of the package, if any, of the case variable
2293
2294 The_Variable : Variable_Value := Nil_Variable_Value;
2295 -- The case variable
2296
2297 Case_Value : Name_Id := No_Name;
2298 -- The case variable value
2299
2300 Case_Item : Project_Node_Id := Empty_Node;
2301 Choice_String : Project_Node_Id := Empty_Node;
2302 Decl_Item : Project_Node_Id := Empty_Node;
2303
2304 begin
2305 declare
2306 Variable_Node : constant Project_Node_Id :=
2307 Case_Variable_Reference_Of
2308 (Current_Item,
2309 Node_Tree);
2310
2311 Var_Id : Variable_Id := No_Variable;
2312 Name : Name_Id := No_Name;
2313
2314 begin
2315 -- If a project was specified for the case variable, get its id
2316
2317 if Present (Project_Node_Of (Variable_Node, Node_Tree)) then
2318 Name :=
2319 Name_Of
2320 (Project_Node_Of (Variable_Node, Node_Tree), Node_Tree);
2321 The_Project :=
2322 Imported_Or_Extended_Project_From
2323 (Project, Name, No_Extending => True);
2324 The_Package := No_Package;
2325 end if;
2326
2327 -- If a package was specified for the case variable, get its id
2328
2329 if Present (Package_Node_Of (Variable_Node, Node_Tree)) then
2330 Name :=
2331 Name_Of
2332 (Package_Node_Of (Variable_Node, Node_Tree), Node_Tree);
2333 The_Package := Package_From (The_Project, Shared, Name);
2334 end if;
2335
2336 Name := Name_Of (Variable_Node, Node_Tree);
2337
2338 -- First, look for the case variable into the package, if any
2339
2340 if The_Package /= No_Package then
2341 Name := Name_Of (Variable_Node, Node_Tree);
2342
2343 Var_Id := Shared.Packages.Table (The_Package).Decl.Variables;
2344 while Var_Id /= No_Variable
2345 and then Shared.Variable_Elements.Table (Var_Id).Name /= Name
2346 loop
2347 Var_Id := Shared.Variable_Elements.Table (Var_Id).Next;
2348 end loop;
2349 end if;
2350
2351 -- If not found in the package, or if there is no package, look at
2352 -- the project level.
2353
2354 if Var_Id = No_Variable
2355 and then No (Package_Node_Of (Variable_Node, Node_Tree))
2356 then
2357 Var_Id := The_Project.Decl.Variables;
2358 while Var_Id /= No_Variable
2359 and then Shared.Variable_Elements.Table (Var_Id).Name /= Name
2360 loop
2361 Var_Id := Shared.Variable_Elements.Table (Var_Id).Next;
2362 end loop;
2363 end if;
2364
2365 if Var_Id = No_Variable then
2366 if Node_Tree.Incomplete_With then
2367 return;
2368
2369 -- Should never happen, because this has already been checked
2370 -- during parsing.
2371
2372 else
2373 Write_Line
2374 ("variable """ & Get_Name_String (Name) & """ not found");
2375 raise Program_Error;
2376 end if;
2377 end if;
2378
2379 -- Get the case variable
2380
2381 The_Variable := Shared.Variable_Elements. Table (Var_Id).Value;
2382
2383 if The_Variable.Kind /= Single then
2384
2385 -- Should never happen, because this has already been checked
2386 -- during parsing.
2387
2388 Write_Line ("variable""" & Get_Name_String (Name) &
2389 """ is not a single string variable");
2390 raise Program_Error;
2391 end if;
2392
2393 -- Get the case variable value
2394
2395 Case_Value := The_Variable.Value;
2396 end;
2397
2398 -- Now look into all the case items of the case construction
2399
2400 Case_Item := First_Case_Item_Of (Current_Item, Node_Tree);
2401
2402 Case_Item_Loop :
2403 while Present (Case_Item) loop
2404 Choice_String := First_Choice_Of (Case_Item, Node_Tree);
2405
2406 -- When Choice_String is nil, it means that it is the
2407 -- "when others =>" alternative.
2408
2409 if No (Choice_String) then
2410 Decl_Item := First_Declarative_Item_Of (Case_Item, Node_Tree);
2411 exit Case_Item_Loop;
2412 end if;
2413
2414 -- Look into all the alternative of this case item
2415
2416 Choice_Loop :
2417 while Present (Choice_String) loop
2418 if Case_Value = String_Value_Of (Choice_String, Node_Tree) then
2419 Decl_Item :=
2420 First_Declarative_Item_Of (Case_Item, Node_Tree);
2421 exit Case_Item_Loop;
2422 end if;
2423
2424 Choice_String := Next_Literal_String (Choice_String, Node_Tree);
2425 end loop Choice_Loop;
2426
2427 Case_Item := Next_Case_Item (Case_Item, Node_Tree);
2428 end loop Case_Item_Loop;
2429
2430 -- If there is an alternative, then we process it
2431
2432 if Present (Decl_Item) then
2433 Process_Declarative_Items
2434 (Project => Project,
2435 In_Tree => In_Tree,
2436 From_Project_Node => From_Project_Node,
2437 Node_Tree => Node_Tree,
2438 Env => Env,
2439 Pkg => Pkg,
2440 Item => Decl_Item,
2441 Child_Env => Child_Env);
2442 end if;
2443 end Process_Case_Construction;
2444
2445 -- Local variables
2446
2447 Current, Decl : Project_Node_Id;
2448 Kind : Project_Node_Kind;
2449
2450 -- Start of processing for Process_Declarative_Items
2451
2452 begin
2453 Decl := Item;
2454 while Present (Decl) loop
2455 Current := Current_Item_Node (Decl, Node_Tree);
2456 Decl := Next_Declarative_Item (Decl, Node_Tree);
2457 Kind := Kind_Of (Current, Node_Tree);
2458
2459 case Kind is
2460 when N_Package_Declaration =>
2461 Process_Package_Declaration (Current);
2462
2463 -- Nothing to process for string type declaration
2464
2465 when N_String_Type_Declaration =>
2466 null;
2467
2468 when N_Attribute_Declaration |
2469 N_Typed_Variable_Declaration |
2470 N_Variable_Declaration =>
2471 Process_Attribute_Declaration (Current);
2472
2473 when N_Case_Construction =>
2474 Process_Case_Construction (Current);
2475
2476 when others =>
2477 Write_Line ("Illegal declarative item: " & Kind'Img);
2478 raise Program_Error;
2479 end case;
2480 end loop;
2481 end Process_Declarative_Items;
2482
2483 ----------------------------------
2484 -- Process_Project_Tree_Phase_1 --
2485 ----------------------------------
2486
2487 procedure Process_Project_Tree_Phase_1
2488 (In_Tree : Project_Tree_Ref;
2489 Project : out Project_Id;
2490 Packages_To_Check : String_List_Access;
2491 Success : out Boolean;
2492 From_Project_Node : Project_Node_Id;
2493 From_Project_Node_Tree : Project_Node_Tree_Ref;
2494 Env : in out Prj.Tree.Environment;
2495 Reset_Tree : Boolean := True;
2496 On_New_Tree_Loaded : Tree_Loaded_Callback := null)
2497 is
2498 begin
2499 if Reset_Tree then
2500
2501 -- Make sure there are no projects in the data structure
2502
2503 Free_List (In_Tree.Projects, Free_Project => True);
2504 end if;
2505
2506 Processed_Projects.Reset;
2507
2508 -- And process the main project and all of the projects it depends on,
2509 -- recursively.
2510
2511 Debug_Increase_Indent ("Process tree, phase 1");
2512
2513 Recursive_Process
2514 (Project => Project,
2515 In_Tree => In_Tree,
2516 Packages_To_Check => Packages_To_Check,
2517 From_Project_Node => From_Project_Node,
2518 From_Project_Node_Tree => From_Project_Node_Tree,
2519 Env => Env,
2520 Extended_By => No_Project,
2521 From_Encapsulated_Lib => False,
2522 On_New_Tree_Loaded => On_New_Tree_Loaded);
2523
2524 Success :=
2525 Total_Errors_Detected = 0
2526 and then
2527 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2528
2529 if Current_Verbosity = High then
2530 Debug_Decrease_Indent
2531 ("Done Process tree, phase 1, Success=" & Success'Img);
2532 end if;
2533 end Process_Project_Tree_Phase_1;
2534
2535 ----------------------------------
2536 -- Process_Project_Tree_Phase_2 --
2537 ----------------------------------
2538
2539 procedure Process_Project_Tree_Phase_2
2540 (In_Tree : Project_Tree_Ref;
2541 Project : Project_Id;
2542 Success : out Boolean;
2543 From_Project_Node : Project_Node_Id;
2544 From_Project_Node_Tree : Project_Node_Tree_Ref;
2545 Env : Environment)
2546 is
2547 Obj_Dir : Path_Name_Type;
2548 Extending : Project_Id;
2549 Extending2 : Project_Id;
2550 Prj : Project_List;
2551
2552 -- Start of processing for Process_Project_Tree_Phase_2
2553
2554 begin
2555 Success := True;
2556
2557 Debug_Increase_Indent ("Process tree, phase 2", Project.Name);
2558
2559 if Project /= No_Project then
2560 Check (In_Tree, Project, From_Project_Node_Tree, Env.Flags);
2561 end if;
2562
2563 -- If main project is an extending all project, set object directory of
2564 -- all virtual extending projects to object directory of main project.
2565
2566 if Project /= No_Project
2567 and then Is_Extending_All (From_Project_Node, From_Project_Node_Tree)
2568 then
2569 declare
2570 Object_Dir : constant Path_Information := Project.Object_Directory;
2571
2572 begin
2573 Prj := In_Tree.Projects;
2574 while Prj /= null loop
2575 if Prj.Project.Virtual then
2576 Prj.Project.Object_Directory := Object_Dir;
2577 end if;
2578
2579 Prj := Prj.Next;
2580 end loop;
2581 end;
2582 end if;
2583
2584 -- Check that no extending project shares its object directory with
2585 -- the project(s) it extends.
2586
2587 if Project /= No_Project then
2588 Prj := In_Tree.Projects;
2589 while Prj /= null loop
2590 Extending := Prj.Project.Extended_By;
2591
2592 if Extending /= No_Project then
2593 Obj_Dir := Prj.Project.Object_Directory.Name;
2594
2595 -- Check that a project being extended does not share its
2596 -- object directory with any project that extends it, directly
2597 -- or indirectly, including a virtual extending project.
2598
2599 -- Start with the project directly extending it
2600
2601 Extending2 := Extending;
2602 while Extending2 /= No_Project loop
2603 if Has_Ada_Sources (Extending2)
2604 and then Extending2.Object_Directory.Name = Obj_Dir
2605 then
2606 if Extending2.Virtual then
2607 Error_Msg_Name_1 := Prj.Project.Display_Name;
2608 Error_Msg
2609 (Env.Flags,
2610 "project %% cannot be extended by a virtual" &
2611 " project with the same object directory",
2612 Prj.Project.Location, Project);
2613
2614 else
2615 Error_Msg_Name_1 := Extending2.Display_Name;
2616 Error_Msg_Name_2 := Prj.Project.Display_Name;
2617 Error_Msg
2618 (Env.Flags,
2619 "project %% cannot extend project %%",
2620 Extending2.Location, Project);
2621 Error_Msg
2622 (Env.Flags,
2623 "\they share the same object directory",
2624 Extending2.Location, Project);
2625 end if;
2626 end if;
2627
2628 -- Continue with the next extending project, if any
2629
2630 Extending2 := Extending2.Extended_By;
2631 end loop;
2632 end if;
2633
2634 Prj := Prj.Next;
2635 end loop;
2636 end if;
2637
2638 Debug_Decrease_Indent ("Done Process tree, phase 2");
2639
2640 Success := Total_Errors_Detected = 0
2641 and then
2642 (Warning_Mode /= Treat_As_Error or else Warnings_Detected = 0);
2643 end Process_Project_Tree_Phase_2;
2644
2645 -----------------------
2646 -- Recursive_Process --
2647 -----------------------
2648
2649 procedure Recursive_Process
2650 (In_Tree : Project_Tree_Ref;
2651 Project : out Project_Id;
2652 Packages_To_Check : String_List_Access;
2653 From_Project_Node : Project_Node_Id;
2654 From_Project_Node_Tree : Project_Node_Tree_Ref;
2655 Env : in out Prj.Tree.Environment;
2656 Extended_By : Project_Id;
2657 From_Encapsulated_Lib : Boolean;
2658 On_New_Tree_Loaded : Tree_Loaded_Callback := null)
2659 is
2660 Shared : constant Shared_Project_Tree_Data_Access := In_Tree.Shared;
2661
2662 Child_Env : Prj.Tree.Environment;
2663 -- Only used for the root aggregate project (if any). This is left
2664 -- uninitialized otherwise.
2665
2666 procedure Process_Imported_Projects
2667 (Imported : in out Project_List;
2668 Limited_With : Boolean);
2669 -- Process imported projects. If Limited_With is True, then only
2670 -- projects processed through a "limited with" are processed, otherwise
2671 -- only projects imported through a standard "with" are processed.
2672 -- Imported is the id of the last imported project.
2673
2674 procedure Process_Aggregated_Projects;
2675 -- Process all the projects aggregated in List. This does nothing if the
2676 -- project is not an aggregate project.
2677
2678 procedure Process_Extended_Project;
2679 -- Process the extended project: inherit all packages from the extended
2680 -- project that are not explicitly defined or renamed. Also inherit the
2681 -- languages, if attribute Languages is not explicitly defined.
2682
2683 -------------------------------
2684 -- Process_Imported_Projects --
2685 -------------------------------
2686
2687 procedure Process_Imported_Projects
2688 (Imported : in out Project_List;
2689 Limited_With : Boolean)
2690 is
2691 With_Clause : Project_Node_Id;
2692 New_Project : Project_Id;
2693 Proj_Node : Project_Node_Id;
2694
2695 begin
2696 With_Clause :=
2697 First_With_Clause_Of
2698 (From_Project_Node, From_Project_Node_Tree);
2699
2700 while Present (With_Clause) loop
2701 Proj_Node :=
2702 Non_Limited_Project_Node_Of
2703 (With_Clause, From_Project_Node_Tree);
2704 New_Project := No_Project;
2705
2706 if (Limited_With and then No (Proj_Node))
2707 or else (not Limited_With and then Present (Proj_Node))
2708 then
2709 Recursive_Process
2710 (In_Tree => In_Tree,
2711 Project => New_Project,
2712 Packages_To_Check => Packages_To_Check,
2713 From_Project_Node =>
2714 Project_Node_Of (With_Clause, From_Project_Node_Tree),
2715 From_Project_Node_Tree => From_Project_Node_Tree,
2716 Env => Env,
2717 Extended_By => No_Project,
2718 From_Encapsulated_Lib => From_Encapsulated_Lib,
2719 On_New_Tree_Loaded => On_New_Tree_Loaded);
2720
2721 if Imported = null then
2722 Project.Imported_Projects := new Project_List_Element'
2723 (Project => New_Project,
2724 From_Encapsulated_Lib => False,
2725 Next => null);
2726 Imported := Project.Imported_Projects;
2727 else
2728 Imported.Next := new Project_List_Element'
2729 (Project => New_Project,
2730 From_Encapsulated_Lib => False,
2731 Next => null);
2732 Imported := Imported.Next;
2733 end if;
2734 end if;
2735
2736 With_Clause :=
2737 Next_With_Clause_Of (With_Clause, From_Project_Node_Tree);
2738 end loop;
2739 end Process_Imported_Projects;
2740
2741 ---------------------------------
2742 -- Process_Aggregated_Projects --
2743 ---------------------------------
2744
2745 procedure Process_Aggregated_Projects is
2746 List : Aggregated_Project_List;
2747 Loaded_Project : Prj.Tree.Project_Node_Id;
2748 Success : Boolean := True;
2749 Tree : Project_Tree_Ref;
2750 Node_Tree : Project_Node_Tree_Ref;
2751
2752 begin
2753 if Project.Qualifier not in Aggregate_Project then
2754 return;
2755 end if;
2756
2757 Debug_Increase_Indent ("Process_Aggregated_Projects", Project.Name);
2758
2759 Prj.Nmsc.Process_Aggregated_Projects
2760 (Tree => In_Tree,
2761 Project => Project,
2762 Node_Tree => From_Project_Node_Tree,
2763 Flags => Env.Flags);
2764
2765 List := Project.Aggregated_Projects;
2766 while Success and then List /= null loop
2767 Node_Tree := new Project_Node_Tree_Data;
2768 Initialize (Node_Tree);
2769
2770 Prj.Part.Parse
2771 (In_Tree => Node_Tree,
2772 Project => Loaded_Project,
2773 Packages_To_Check => Packages_To_Check,
2774 Project_File_Name => Get_Name_String (List.Path),
2775 Errout_Handling => Prj.Part.Never_Finalize,
2776 Current_Directory => Get_Name_String (Project.Directory.Name),
2777 Is_Config_File => False,
2778 Env => Child_Env);
2779
2780 Success := not Prj.Tree.No (Loaded_Project);
2781
2782 if Success then
2783 if Node_Tree.Incomplete_With then
2784 From_Project_Node_Tree.Incomplete_With := True;
2785 end if;
2786
2787 List.Tree := new Project_Tree_Data (Is_Root_Tree => False);
2788 Prj.Initialize (List.Tree);
2789 List.Tree.Shared := In_Tree.Shared;
2790
2791 -- In aggregate library, aggregated projects are parsed using
2792 -- the aggregate library tree.
2793
2794 if Project.Qualifier = Aggregate_Library then
2795 Tree := In_Tree;
2796 else
2797 Tree := List.Tree;
2798 end if;
2799
2800 -- We can only do the phase 1 of the processing, since we do
2801 -- not have access to the configuration file yet (this is
2802 -- called when doing phase 1 of the processing for the root
2803 -- aggregate project).
2804
2805 if In_Tree.Is_Root_Tree then
2806 Process_Project_Tree_Phase_1
2807 (In_Tree => Tree,
2808 Project => List.Project,
2809 Packages_To_Check => Packages_To_Check,
2810 Success => Success,
2811 From_Project_Node => Loaded_Project,
2812 From_Project_Node_Tree => Node_Tree,
2813 Env => Child_Env,
2814 Reset_Tree => False,
2815 On_New_Tree_Loaded => On_New_Tree_Loaded);
2816 else
2817 -- use the same environment as the rest of the aggregated
2818 -- projects, ie the one that was setup by the root aggregate
2819 Process_Project_Tree_Phase_1
2820 (In_Tree => Tree,
2821 Project => List.Project,
2822 Packages_To_Check => Packages_To_Check,
2823 Success => Success,
2824 From_Project_Node => Loaded_Project,
2825 From_Project_Node_Tree => Node_Tree,
2826 Env => Env,
2827 Reset_Tree => False,
2828 On_New_Tree_Loaded => On_New_Tree_Loaded);
2829 end if;
2830
2831 if On_New_Tree_Loaded /= null then
2832 On_New_Tree_Loaded
2833 (Node_Tree, Tree, Loaded_Project, List.Project);
2834 end if;
2835
2836 else
2837 Debug_Output ("Failed to parse", Name_Id (List.Path));
2838 end if;
2839
2840 List := List.Next;
2841 end loop;
2842
2843 Debug_Decrease_Indent ("Done Process_Aggregated_Projects");
2844 end Process_Aggregated_Projects;
2845
2846 ------------------------------
2847 -- Process_Extended_Project --
2848 ------------------------------
2849
2850 procedure Process_Extended_Project is
2851 Extended_Pkg : Package_Id;
2852 Current_Pkg : Package_Id;
2853 Element : Package_Element;
2854 First : constant Package_Id := Project.Decl.Packages;
2855 Attribute1 : Variable_Id;
2856 Attribute2 : Variable_Id;
2857 Attr_Value1 : Variable;
2858 Attr_Value2 : Variable;
2859
2860 begin
2861 Extended_Pkg := Project.Extends.Decl.Packages;
2862 while Extended_Pkg /= No_Package loop
2863 Element := Shared.Packages.Table (Extended_Pkg);
2864
2865 Current_Pkg := First;
2866 while Current_Pkg /= No_Package
2867 and then
2868 Shared.Packages.Table (Current_Pkg).Name /= Element.Name
2869 loop
2870 Current_Pkg := Shared.Packages.Table (Current_Pkg).Next;
2871 end loop;
2872
2873 if Current_Pkg = No_Package then
2874 Package_Table.Increment_Last (Shared.Packages);
2875 Current_Pkg := Package_Table.Last (Shared.Packages);
2876 Shared.Packages.Table (Current_Pkg) :=
2877 (Name => Element.Name,
2878 Decl => No_Declarations,
2879 Parent => No_Package,
2880 Next => Project.Decl.Packages);
2881 Project.Decl.Packages := Current_Pkg;
2882 Copy_Package_Declarations
2883 (From => Element.Decl,
2884 To => Shared.Packages.Table (Current_Pkg).Decl,
2885 New_Loc => No_Location,
2886 Restricted => True,
2887 Shared => Shared);
2888 end if;
2889
2890 Extended_Pkg := Element.Next;
2891 end loop;
2892
2893 -- Check if attribute Languages is declared in the extending project
2894
2895 Attribute1 := Project.Decl.Attributes;
2896 while Attribute1 /= No_Variable loop
2897 Attr_Value1 := Shared.Variable_Elements. Table (Attribute1);
2898 exit when Attr_Value1.Name = Snames.Name_Languages;
2899 Attribute1 := Attr_Value1.Next;
2900 end loop;
2901
2902 if Attribute1 = No_Variable or else Attr_Value1.Value.Default then
2903
2904 -- Attribute Languages is not declared in the extending project.
2905 -- Check if it is declared in the project being extended.
2906
2907 Attribute2 := Project.Extends.Decl.Attributes;
2908 while Attribute2 /= No_Variable loop
2909 Attr_Value2 := Shared.Variable_Elements.Table (Attribute2);
2910 exit when Attr_Value2.Name = Snames.Name_Languages;
2911 Attribute2 := Attr_Value2.Next;
2912 end loop;
2913
2914 if Attribute2 /= No_Variable
2915 and then not Attr_Value2.Value.Default
2916 then
2917 -- As attribute Languages is declared in the project being
2918 -- extended, copy its value for the extending project.
2919
2920 if Attribute1 = No_Variable then
2921 Variable_Element_Table.Increment_Last
2922 (Shared.Variable_Elements);
2923 Attribute1 := Variable_Element_Table.Last
2924 (Shared.Variable_Elements);
2925 Attr_Value1.Next := Project.Decl.Attributes;
2926 Project.Decl.Attributes := Attribute1;
2927 end if;
2928
2929 Attr_Value1.Name := Snames.Name_Languages;
2930 Attr_Value1.Value := Attr_Value2.Value;
2931 Shared.Variable_Elements.Table (Attribute1) := Attr_Value1;
2932 end if;
2933 end if;
2934 end Process_Extended_Project;
2935
2936 -- Start of processing for Recursive_Process
2937
2938 begin
2939 if No (From_Project_Node) then
2940 Project := No_Project;
2941
2942 else
2943 declare
2944 Imported, Mark : Project_List;
2945 Declaration_Node : Project_Node_Id := Empty_Node;
2946
2947 Name : constant Name_Id :=
2948 Name_Of (From_Project_Node, From_Project_Node_Tree);
2949
2950 Display_Name : constant Name_Id :=
2951 Display_Name_Of
2952 (From_Project_Node, From_Project_Node_Tree);
2953
2954 begin
2955 Project := Processed_Projects.Get (Name);
2956
2957 if Project /= No_Project then
2958
2959 -- Make sure that, when a project is extended, the project id
2960 -- of the project extending it is recorded in its data, even
2961 -- when it has already been processed as an imported project.
2962 -- This is for virtually extended projects.
2963
2964 if Extended_By /= No_Project then
2965 Project.Extended_By := Extended_By;
2966 end if;
2967
2968 return;
2969 end if;
2970
2971 -- Check if the project is already in the tree
2972
2973 Project := No_Project;
2974
2975 declare
2976 List : Project_List := In_Tree.Projects;
2977 Path : constant Path_Name_Type :=
2978 Path_Name_Of (From_Project_Node,
2979 From_Project_Node_Tree);
2980
2981 begin
2982 while List /= null loop
2983 if List.Project.Path.Display_Name = Path then
2984 Project := List.Project;
2985 exit;
2986 end if;
2987
2988 List := List.Next;
2989 end loop;
2990 end;
2991
2992 if Project = No_Project then
2993 Project :=
2994 new Project_Data'
2995 (Empty_Project
2996 (Project_Qualifier_Of
2997 (From_Project_Node, From_Project_Node_Tree)));
2998
2999 -- Note that at this point we do not know yet if the project
3000 -- has been withed from an encapsulated library or not.
3001
3002 In_Tree.Projects :=
3003 new Project_List_Element'
3004 (Project => Project,
3005 From_Encapsulated_Lib => False,
3006 Next => In_Tree.Projects);
3007 end if;
3008
3009 -- Keep track of this point
3010
3011 Mark := In_Tree.Projects;
3012
3013 Processed_Projects.Set (Name, Project);
3014
3015 Project.Name := Name;
3016 Project.Display_Name := Display_Name;
3017
3018 Get_Name_String (Name);
3019
3020 -- If name starts with the virtual prefix, flag the project as
3021 -- being a virtual extending project.
3022
3023 if Name_Len > Virtual_Prefix'Length
3024 and then
3025 Name_Buffer (1 .. Virtual_Prefix'Length) = Virtual_Prefix
3026 then
3027 Project.Virtual := True;
3028 end if;
3029
3030 Project.Path.Display_Name :=
3031 Path_Name_Of (From_Project_Node, From_Project_Node_Tree);
3032 Get_Name_String (Project.Path.Display_Name);
3033 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3034 Project.Path.Name := Name_Find;
3035
3036 Project.Location :=
3037 Location_Of (From_Project_Node, From_Project_Node_Tree);
3038
3039 Project.Directory.Display_Name :=
3040 Directory_Of (From_Project_Node, From_Project_Node_Tree);
3041 Get_Name_String (Project.Directory.Display_Name);
3042 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3043 Project.Directory.Name := Name_Find;
3044
3045 Project.Extended_By := Extended_By;
3046
3047 Add_Attributes
3048 (Project,
3049 Name,
3050 Name_Id (Project.Directory.Display_Name),
3051 In_Tree.Shared,
3052 Project.Decl,
3053 Prj.Attr.Attribute_First,
3054 Project_Level => True);
3055
3056 Process_Imported_Projects (Imported, Limited_With => False);
3057
3058 if Project.Qualifier = Aggregate then
3059 Initialize_And_Copy (Child_Env, Copy_From => Env);
3060
3061 elsif Project.Qualifier = Aggregate_Library then
3062
3063 -- The child environment is the same as the current one
3064
3065 Child_Env := Env;
3066
3067 else
3068 -- No need to initialize Child_Env, since it will not be
3069 -- used anyway by Process_Declarative_Items (only the root
3070 -- aggregate can modify it, and it is never read anyway).
3071
3072 null;
3073 end if;
3074
3075 Declaration_Node :=
3076 Project_Declaration_Of
3077 (From_Project_Node, From_Project_Node_Tree);
3078
3079 Recursive_Process
3080 (In_Tree => In_Tree,
3081 Project => Project.Extends,
3082 Packages_To_Check => Packages_To_Check,
3083 From_Project_Node =>
3084 Extended_Project_Of
3085 (Declaration_Node, From_Project_Node_Tree),
3086 From_Project_Node_Tree => From_Project_Node_Tree,
3087 Env => Env,
3088 Extended_By => Project,
3089 From_Encapsulated_Lib => From_Encapsulated_Lib,
3090 On_New_Tree_Loaded => On_New_Tree_Loaded);
3091
3092 Process_Declarative_Items
3093 (Project => Project,
3094 In_Tree => In_Tree,
3095 From_Project_Node => From_Project_Node,
3096 Node_Tree => From_Project_Node_Tree,
3097 Env => Env,
3098 Pkg => No_Package,
3099 Item => First_Declarative_Item_Of
3100 (Declaration_Node, From_Project_Node_Tree),
3101 Child_Env => Child_Env);
3102
3103 if Project.Extends /= No_Project then
3104 Process_Extended_Project;
3105 end if;
3106
3107 Process_Imported_Projects (Imported, Limited_With => True);
3108
3109 if Total_Errors_Detected = 0 then
3110 Process_Aggregated_Projects;
3111 end if;
3112
3113 -- At this point (after Process_Declarative_Items) we have the
3114 -- attribute values set, we can backtrace In_Tree.Project and
3115 -- set the From_Encapsulated_Library status.
3116
3117 declare
3118 Lib_Standalone : constant Prj.Variable_Value :=
3119 Prj.Util.Value_Of
3120 (Snames.Name_Library_Standalone,
3121 Project.Decl.Attributes,
3122 Shared);
3123 List : Project_List := In_Tree.Projects;
3124 Is_Encapsulated : Boolean;
3125
3126 begin
3127 Get_Name_String (Lib_Standalone.Value);
3128 To_Lower (Name_Buffer (1 .. Name_Len));
3129
3130 Is_Encapsulated := Name_Buffer (1 .. Name_Len) = "encapsulated";
3131
3132 if Is_Encapsulated then
3133 while List /= null and then List /= Mark loop
3134 List.From_Encapsulated_Lib := Is_Encapsulated;
3135 List := List.Next;
3136 end loop;
3137 end if;
3138
3139 if Total_Errors_Detected = 0 then
3140
3141 -- For an aggregate library we add the aggregated projects
3142 -- as imported ones. This is necessary to give visibility
3143 -- to all sources from the aggregates from the aggregated
3144 -- library projects.
3145
3146 if Project.Qualifier = Aggregate_Library then
3147 declare
3148 L : Aggregated_Project_List;
3149 begin
3150 L := Project.Aggregated_Projects;
3151 while L /= null loop
3152 Project.Imported_Projects :=
3153 new Project_List_Element'
3154 (Project => L.Project,
3155 From_Encapsulated_Lib => Is_Encapsulated,
3156 Next =>
3157 Project.Imported_Projects);
3158 L := L.Next;
3159 end loop;
3160 end;
3161 end if;
3162 end if;
3163 end;
3164
3165 if Project.Qualifier = Aggregate and then In_Tree.Is_Root_Tree then
3166 Free (Child_Env);
3167 end if;
3168 end;
3169 end if;
3170 end Recursive_Process;
3171
3172 -----------------------------
3173 -- Set_Default_Runtime_For --
3174 -----------------------------
3175
3176 procedure Set_Default_Runtime_For (Language : Name_Id; Value : String) is
3177 begin
3178 Name_Len := Value'Length;
3179 Name_Buffer (1 .. Name_Len) := Value;
3180 Runtime_Defaults.Set (Language, Name_Find);
3181 end Set_Default_Runtime_For;
3182 end Prj.Proc;