1 ------------------------------------------------------------------------------
4 -- GNAT COMPILER COMPONENTS --
10 -- Copyright (C) 2001-2007, Free Software Foundation, Inc. --
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. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Err_Vars
; use Err_Vars
;
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
;
38 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
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
,
52 -- This hash table contains all processed projects
54 package Unit_Htable
is new GNAT
.HTable
.Simple_HTable
55 (Header_Num
=> Header_Num
,
57 No_Element
=> No_Source
,
61 -- This hash table contains all processed projects
63 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
);
64 -- Concatenate two strings and returns another string if both
65 -- arguments are not null string.
67 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.
78 (In_Tree
: Project_Tree_Ref
;
80 Follow_Links
: Boolean;
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.
85 procedure Copy_Package_Declarations
87 To
: in out Declarations
;
89 In_Tree
: Project_Tree_Ref
);
90 -- Copy a package declaration From to To for a renamed package. Change the
91 -- locations of all the attributes to New_Loc.
94 (Project
: Project_Id
;
95 In_Tree
: Project_Tree_Ref
;
96 From_Project_Node
: Project_Node_Id
;
97 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
99 First_Term
: Project_Node_Id
;
100 Kind
: Variable_Kind
) return Variable_Value
;
101 -- From N_Expression project node From_Project_Node, compute the value
102 -- of an expression and return it as a Variable_Value.
104 function Imported_Or_Extended_Project_From
105 (Project
: Project_Id
;
106 In_Tree
: Project_Tree_Ref
;
107 With_Name
: Name_Id
) return Project_Id
;
108 -- Find an imported or extended project of Project whose name is With_Name
110 function Package_From
111 (Project
: Project_Id
;
112 In_Tree
: Project_Tree_Ref
;
113 With_Name
: Name_Id
) return Package_Id
;
114 -- Find the package of Project whose name is With_Name
116 procedure Process_Declarative_Items
117 (Project
: Project_Id
;
118 In_Tree
: Project_Tree_Ref
;
119 From_Project_Node
: Project_Node_Id
;
120 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
122 Item
: Project_Node_Id
);
123 -- Process declarative items starting with From_Project_Node, and put them
124 -- in declarations Decl. This is a recursive procedure; it calls itself for
125 -- a package declaration or a case construction.
127 procedure Recursive_Process
128 (In_Tree
: Project_Tree_Ref
;
129 Project
: out Project_Id
;
130 From_Project_Node
: Project_Node_Id
;
131 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
132 Extended_By
: Project_Id
);
133 -- Process project with node From_Project_Node in the tree.
134 -- Do nothing if From_Project_Node is Empty_Node.
135 -- If project has already been processed, simply return its project id.
136 -- Otherwise create a new project id, mark it as processed, call itself
137 -- recursively for all imported projects and a extended project, if any.
138 -- Then process the declarative items of the project.
140 procedure Recursive_Check
141 (Project
: Project_Id
;
142 In_Tree
: Project_Tree_Ref
;
143 Follow_Links
: Boolean;
144 When_No_Sources
: Error_Warning
);
145 -- If Project is not marked as checked, mark it as checked, call
146 -- Check_Naming_Scheme for the project, then call itself for a
147 -- possible extended project and all the imported projects of Project.
153 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
) is
155 if To_Exp
= No_Name
or else To_Exp
= Empty_String
then
157 -- To_Exp is nil or empty. The result is Str
161 -- If Str is nil, then do not change To_Ext
163 elsif Str
/= No_Name
and then Str
/= Empty_String
then
165 S
: constant String := Get_Name_String
(Str
);
168 Get_Name_String
(To_Exp
);
169 Add_Str_To_Name_Buffer
(S
);
179 procedure Add_Attributes
180 (Project
: Project_Id
;
181 Project_Name
: Name_Id
;
182 In_Tree
: Project_Tree_Ref
;
183 Decl
: in out Declarations
;
184 First
: Attribute_Node_Id
;
185 Project_Level
: Boolean)
187 The_Attribute
: Attribute_Node_Id
:= First
;
190 while The_Attribute
/= Empty_Attribute
loop
191 if Attribute_Kind_Of
(The_Attribute
) = Single
then
193 New_Attribute
: Variable_Value
;
196 case Variable_Kind_Of
(The_Attribute
) is
198 -- Undefined should not happen
202 (False, "attribute with an undefined kind");
205 -- Single attributes have a default value of empty string
211 Location
=> No_Location
,
213 Value
=> Empty_String
,
216 -- Special case of <project>'Name
219 and then Attribute_Name_Of
(The_Attribute
) =
222 New_Attribute
.Value
:= Project_Name
;
225 -- List attributes have a default value of nil list
231 Location
=> No_Location
,
233 Values
=> Nil_String
);
237 Variable_Element_Table
.Increment_Last
238 (In_Tree
.Variable_Elements
);
239 In_Tree
.Variable_Elements
.Table
240 (Variable_Element_Table
.Last
241 (In_Tree
.Variable_Elements
)) :=
242 (Next
=> Decl
.Attributes
,
243 Name
=> Attribute_Name_Of
(The_Attribute
),
244 Value
=> New_Attribute
);
245 Decl
.Attributes
:= Variable_Element_Table
.Last
246 (In_Tree
.Variable_Elements
);
250 The_Attribute
:= Next_Attribute
(After
=> The_Attribute
);
259 (In_Tree
: Project_Tree_Ref
;
260 Project
: Project_Id
;
261 Follow_Links
: Boolean;
262 When_No_Sources
: Error_Warning
)
265 -- Make sure that all projects are marked as not checked
267 for Index
in Project_Table
.First
..
268 Project_Table
.Last
(In_Tree
.Projects
)
270 In_Tree
.Projects
.Table
(Index
).Checked
:= False;
274 (Project
, In_Tree
, Follow_Links
, When_No_Sources
);
276 -- Set the Other_Part field for the units
286 Source1
:= In_Tree
.First_Source
;
287 while Source1
/= No_Source
loop
288 Name
:= In_Tree
.Sources
.Table
(Source1
).Unit
;
290 if Name
/= No_Name
then
291 Source2
:= Unit_Htable
.Get
(Name
);
293 if Source2
= No_Source
then
294 Unit_Htable
.Set
(K
=> Name
, E
=> Source1
);
297 Unit_Htable
.Remove
(Name
);
298 In_Tree
.Sources
.Table
(Source1
).Other_Part
:= Source2
;
299 In_Tree
.Sources
.Table
(Source2
).Other_Part
:= Source1
;
303 Source1
:= In_Tree
.Sources
.Table
(Source1
).Next_In_Sources
;
308 -------------------------------
309 -- Copy_Package_Declarations --
310 -------------------------------
312 procedure Copy_Package_Declarations
313 (From
: Declarations
;
314 To
: in out Declarations
;
315 New_Loc
: Source_Ptr
;
316 In_Tree
: Project_Tree_Ref
)
318 V1
: Variable_Id
:= From
.Attributes
;
319 V2
: Variable_Id
:= No_Variable
;
321 A1
: Array_Id
:= From
.Arrays
;
322 A2
: Array_Id
:= No_Array
;
324 E1
: Array_Element_Id
;
325 E2
: Array_Element_Id
:= No_Array_Element
;
329 -- To avoid references in error messages to attribute declarations in
330 -- an original package that has been renamed, copy all the attribute
331 -- declarations of the package and change all locations to New_Loc,
332 -- the location of the renamed package.
334 -- First single attributes
336 while V1
/= No_Variable
loop
338 -- Copy the attribute
340 Var
:= In_Tree
.Variable_Elements
.Table
(V1
);
343 -- Remove the Next component
345 Var
.Next
:= No_Variable
;
347 -- Change the location to New_Loc
349 Var
.Value
.Location
:= New_Loc
;
350 Variable_Element_Table
.Increment_Last
(In_Tree
.Variable_Elements
);
352 -- Put in new declaration
354 if To
.Attributes
= No_Variable
then
356 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
359 In_Tree
.Variable_Elements
.Table
(V2
).Next
:=
360 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
363 V2
:= Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
364 In_Tree
.Variable_Elements
.Table
(V2
) := Var
;
367 -- Then the associated array attributes
369 while A1
/= No_Array
loop
373 Arr
:= In_Tree
.Arrays
.Table
(A1
);
376 -- Remove the Next component
378 Arr
.Next
:= No_Array
;
380 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
382 -- Create new Array declaration
383 if To
.Arrays
= No_Array
then
384 To
.Arrays
:= Array_Table
.Last
(In_Tree
.Arrays
);
387 In_Tree
.Arrays
.Table
(A2
).Next
:=
388 Array_Table
.Last
(In_Tree
.Arrays
);
391 A2
:= Array_Table
.Last
(In_Tree
.Arrays
);
393 -- Don't store the array, as its first element has not been set yet
395 -- Copy the array elements of the array
398 Arr
.Value
:= No_Array_Element
;
400 while E1
/= No_Array_Element
loop
402 -- Copy the array element
404 Elm
:= In_Tree
.Array_Elements
.Table
(E1
);
407 -- Remove the Next component
409 Elm
.Next
:= No_Array_Element
;
411 -- Change the location
413 Elm
.Value
.Location
:= New_Loc
;
414 Array_Element_Table
.Increment_Last
(In_Tree
.Array_Elements
);
416 -- Create new array element
418 if Arr
.Value
= No_Array_Element
then
419 Arr
.Value
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
421 In_Tree
.Array_Elements
.Table
(E2
).Next
:=
422 Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
425 E2
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
426 In_Tree
.Array_Elements
.Table
(E2
) := Elm
;
429 -- Finally, store the new array
431 In_Tree
.Arrays
.Table
(A2
) := Arr
;
433 end Copy_Package_Declarations
;
440 (Project
: Project_Id
;
441 In_Tree
: Project_Tree_Ref
;
442 From_Project_Node
: Project_Node_Id
;
443 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
445 First_Term
: Project_Node_Id
;
446 Kind
: Variable_Kind
) return Variable_Value
448 The_Term
: Project_Node_Id
:= First_Term
;
449 -- The term in the expression list
451 The_Current_Term
: Project_Node_Id
:= Empty_Node
;
452 -- The current term node id
454 Result
: Variable_Value
(Kind
=> Kind
);
455 -- The returned result
457 Last
: String_List_Id
:= Nil_String
;
458 -- Reference to the last string elements in Result, when Kind is List
461 Result
.Project
:= Project
;
462 Result
.Location
:= Location_Of
(First_Term
, From_Project_Node_Tree
);
464 -- Process each term of the expression, starting with First_Term
466 while The_Term
/= Empty_Node
loop
467 The_Current_Term
:= Current_Term
(The_Term
, From_Project_Node_Tree
);
469 case Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) is
471 when N_Literal_String
=>
477 -- Should never happen
479 pragma Assert
(False, "Undefined expression kind");
485 (The_Current_Term
, From_Project_Node_Tree
));
488 (The_Current_Term
, From_Project_Node_Tree
);
492 String_Element_Table
.Increment_Last
493 (In_Tree
.String_Elements
);
495 if Last
= Nil_String
then
497 -- This can happen in an expression like () & "toto"
499 Result
.Values
:= String_Element_Table
.Last
500 (In_Tree
.String_Elements
);
503 In_Tree
.String_Elements
.Table
504 (Last
).Next
:= String_Element_Table
.Last
505 (In_Tree
.String_Elements
);
508 Last
:= String_Element_Table
.Last
509 (In_Tree
.String_Elements
);
510 In_Tree
.String_Elements
.Table
(Last
) :=
514 From_Project_Node_Tree
),
517 (The_Current_Term
, From_Project_Node_Tree
),
518 Display_Value
=> No_Name
,
522 From_Project_Node_Tree
),
527 when N_Literal_String_List
=>
530 String_Node
: Project_Node_Id
:=
531 First_Expression_In_List
533 From_Project_Node_Tree
);
535 Value
: Variable_Value
;
538 if String_Node
/= Empty_Node
then
540 -- If String_Node is nil, it is an empty list,
541 -- there is nothing to do
546 From_Project_Node
=> From_Project_Node
,
547 From_Project_Node_Tree
=> From_Project_Node_Tree
,
551 (String_Node
, From_Project_Node_Tree
),
553 String_Element_Table
.Increment_Last
554 (In_Tree
.String_Elements
);
556 if Result
.Values
= Nil_String
then
558 -- This literal string list is the first term
559 -- in a string list expression
562 String_Element_Table
.Last
(In_Tree
.String_Elements
);
565 In_Tree
.String_Elements
.Table
567 String_Element_Table
.Last
(In_Tree
.String_Elements
);
571 String_Element_Table
.Last
(In_Tree
.String_Elements
);
573 In_Tree
.String_Elements
.Table
(Last
) :=
574 (Value
=> Value
.Value
,
575 Display_Value
=> No_Name
,
576 Location
=> Value
.Location
,
579 Index
=> Value
.Index
);
582 -- Add the other element of the literal string list
583 -- one after the other
586 Next_Expression_In_List
587 (String_Node
, From_Project_Node_Tree
);
589 exit when String_Node
= Empty_Node
;
595 From_Project_Node
=> From_Project_Node
,
596 From_Project_Node_Tree
=> From_Project_Node_Tree
,
600 (String_Node
, From_Project_Node_Tree
),
603 String_Element_Table
.Increment_Last
604 (In_Tree
.String_Elements
);
605 In_Tree
.String_Elements
.Table
606 (Last
).Next
:= String_Element_Table
.Last
607 (In_Tree
.String_Elements
);
608 Last
:= String_Element_Table
.Last
609 (In_Tree
.String_Elements
);
610 In_Tree
.String_Elements
.Table
(Last
) :=
611 (Value
=> Value
.Value
,
612 Display_Value
=> No_Name
,
613 Location
=> Value
.Location
,
616 Index
=> Value
.Index
);
621 when N_Variable_Reference | N_Attribute_Reference
=>
624 The_Project
: Project_Id
:= Project
;
625 The_Package
: Package_Id
:= Pkg
;
626 The_Name
: Name_Id
:= No_Name
;
627 The_Variable_Id
: Variable_Id
:= No_Variable
;
628 The_Variable
: Variable_Value
;
629 Term_Project
: constant Project_Node_Id
:=
632 From_Project_Node_Tree
);
633 Term_Package
: constant Project_Node_Id
:=
636 From_Project_Node_Tree
);
637 Index
: Name_Id
:= No_Name
;
640 if Term_Project
/= Empty_Node
and then
641 Term_Project
/= From_Project_Node
643 -- This variable or attribute comes from another project
646 Name_Of
(Term_Project
, From_Project_Node_Tree
);
647 The_Project
:= Imported_Or_Extended_Project_From
650 With_Name
=> The_Name
);
653 if Term_Package
/= Empty_Node
then
655 -- This is an attribute of a package
658 Name_Of
(Term_Package
, From_Project_Node_Tree
);
659 The_Package
:= In_Tree
.Projects
.Table
660 (The_Project
).Decl
.Packages
;
662 while The_Package
/= No_Package
663 and then In_Tree
.Packages
.Table
664 (The_Package
).Name
/= The_Name
667 In_Tree
.Packages
.Table
672 (The_Package
/= No_Package
,
673 "package not found.");
675 elsif Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
676 N_Attribute_Reference
678 The_Package
:= No_Package
;
682 Name_Of
(The_Current_Term
, From_Project_Node_Tree
);
684 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
685 N_Attribute_Reference
688 Associative_Array_Index_Of
689 (The_Current_Term
, From_Project_Node_Tree
);
692 -- If it is not an associative array attribute
694 if Index
= No_Name
then
696 -- It is not an associative array attribute
698 if The_Package
/= No_Package
then
700 -- First, if there is a package, look into the package
702 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
706 In_Tree
.Packages
.Table
707 (The_Package
).Decl
.Variables
;
710 In_Tree
.Packages
.Table
711 (The_Package
).Decl
.Attributes
;
714 while The_Variable_Id
/= No_Variable
716 In_Tree
.Variable_Elements
.Table
717 (The_Variable_Id
).Name
/= The_Name
720 In_Tree
.Variable_Elements
.Table
721 (The_Variable_Id
).Next
;
726 if The_Variable_Id
= No_Variable
then
728 -- If we have not found it, look into the project
730 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
734 In_Tree
.Projects
.Table
735 (The_Project
).Decl
.Variables
;
738 In_Tree
.Projects
.Table
739 (The_Project
).Decl
.Attributes
;
742 while The_Variable_Id
/= No_Variable
744 In_Tree
.Variable_Elements
.Table
745 (The_Variable_Id
).Name
/= The_Name
748 In_Tree
.Variable_Elements
.Table
749 (The_Variable_Id
).Next
;
754 pragma Assert
(The_Variable_Id
/= No_Variable
,
755 "variable or attribute not found");
758 In_Tree
.Variable_Elements
.Table
759 (The_Variable_Id
).Value
;
763 -- It is an associative array attribute
766 The_Array
: Array_Id
:= No_Array
;
767 The_Element
: Array_Element_Id
:= No_Array_Element
;
768 Array_Index
: Name_Id
:= No_Name
;
771 if The_Package
/= No_Package
then
773 In_Tree
.Packages
.Table
774 (The_Package
).Decl
.Arrays
;
777 In_Tree
.Projects
.Table
778 (The_Project
).Decl
.Arrays
;
781 while The_Array
/= No_Array
782 and then In_Tree
.Arrays
.Table
783 (The_Array
).Name
/= The_Name
785 The_Array
:= In_Tree
.Arrays
.Table
789 if The_Array
/= No_Array
then
790 The_Element
:= In_Tree
.Arrays
.Table
793 Get_Name_String
(Index
);
796 (The_Current_Term
, From_Project_Node_Tree
)
798 To_Lower
(Name_Buffer
(1 .. Name_Len
));
801 Array_Index
:= Name_Find
;
803 while The_Element
/= No_Array_Element
805 In_Tree
.Array_Elements
.Table
806 (The_Element
).Index
/= Array_Index
809 In_Tree
.Array_Elements
.Table
815 if The_Element
/= No_Array_Element
then
817 In_Tree
.Array_Elements
.Table
821 if Expression_Kind_Of
822 (The_Current_Term
, From_Project_Node_Tree
) =
828 Location
=> No_Location
,
830 Values
=> Nil_String
);
835 Location
=> No_Location
,
837 Value
=> Empty_String
,
848 -- Should never happen
850 pragma Assert
(False, "undefined expression kind");
855 case The_Variable
.Kind
is
861 Add
(Result
.Value
, The_Variable
.Value
);
865 -- Should never happen
869 "list cannot appear in single " &
870 "string expression");
875 case The_Variable
.Kind
is
881 String_Element_Table
.Increment_Last
882 (In_Tree
.String_Elements
);
884 if Last
= Nil_String
then
886 -- This can happen in an expression such as
890 String_Element_Table
.Last
891 (In_Tree
.String_Elements
);
894 In_Tree
.String_Elements
.Table
896 String_Element_Table
.Last
897 (In_Tree
.String_Elements
);
901 String_Element_Table
.Last
902 (In_Tree
.String_Elements
);
904 In_Tree
.String_Elements
.Table
(Last
) :=
905 (Value
=> The_Variable
.Value
,
906 Display_Value
=> No_Name
,
907 Location
=> Location_Of
909 From_Project_Node_Tree
),
917 The_List
: String_List_Id
:=
921 while The_List
/= Nil_String
loop
922 String_Element_Table
.Increment_Last
923 (In_Tree
.String_Elements
);
925 if Last
= Nil_String
then
927 String_Element_Table
.Last
933 String_Elements
.Table
(Last
).Next
:=
934 String_Element_Table
.Last
941 String_Element_Table
.Last
942 (In_Tree
.String_Elements
);
944 In_Tree
.String_Elements
.Table
(Last
) :=
946 In_Tree
.String_Elements
.Table
948 Display_Value
=> No_Name
,
952 From_Project_Node_Tree
),
958 In_Tree
. String_Elements
.Table
966 when N_External_Value
=>
969 (External_Reference_Of
970 (The_Current_Term
, From_Project_Node_Tree
),
971 From_Project_Node_Tree
));
974 Name
: constant Name_Id
:= Name_Find
;
975 Default
: Name_Id
:= No_Name
;
976 Value
: Name_Id
:= No_Name
;
978 Def_Var
: Variable_Value
;
980 Default_Node
: constant Project_Node_Id
:=
982 (The_Current_Term
, From_Project_Node_Tree
);
985 -- If there is a default value for the external reference,
988 if Default_Node
/= Empty_Node
then
989 Def_Var
:= Expression
992 From_Project_Node
=> Default_Node
,
993 From_Project_Node_Tree
=> From_Project_Node_Tree
,
997 (Default_Node
, From_Project_Node_Tree
),
1000 if Def_Var
/= Nil_Variable_Value
then
1001 Default
:= Def_Var
.Value
;
1005 Value
:= Prj
.Ext
.Value_Of
(Name
, Default
);
1007 if Value
= No_Name
then
1008 if not Quiet_Output
then
1009 if Error_Report
= null then
1011 ("?undefined external reference",
1013 (The_Current_Term
, From_Project_Node_Tree
));
1016 ("warning: """ & Get_Name_String
(Name
) &
1017 """ is an undefined external reference",
1022 Value
:= Empty_String
;
1031 Add
(Result
.Value
, Value
);
1034 String_Element_Table
.Increment_Last
1035 (In_Tree
.String_Elements
);
1037 if Last
= Nil_String
then
1038 Result
.Values
:= String_Element_Table
.Last
1039 (In_Tree
.String_Elements
);
1042 In_Tree
.String_Elements
.Table
1043 (Last
).Next
:= String_Element_Table
.Last
1044 (In_Tree
.String_Elements
);
1047 Last
:= String_Element_Table
.Last
1048 (In_Tree
.String_Elements
);
1049 In_Tree
.String_Elements
.Table
(Last
) :=
1051 Display_Value
=> No_Name
,
1054 (The_Current_Term
, From_Project_Node_Tree
),
1064 -- Should never happen
1068 "illegal node kind in an expression");
1069 raise Program_Error
;
1073 The_Term
:= Next_Term
(The_Term
, From_Project_Node_Tree
);
1079 ---------------------------------------
1080 -- Imported_Or_Extended_Project_From --
1081 ---------------------------------------
1083 function Imported_Or_Extended_Project_From
1084 (Project
: Project_Id
;
1085 In_Tree
: Project_Tree_Ref
;
1086 With_Name
: Name_Id
) return Project_Id
1088 Data
: constant Project_Data
:=
1089 In_Tree
.Projects
.Table
(Project
);
1090 List
: Project_List
:= Data
.Imported_Projects
;
1091 Result
: Project_Id
:= No_Project
;
1092 Temp_Result
: Project_Id
:= No_Project
;
1095 -- First check if it is the name of an extended project
1097 if Data
.Extends
/= No_Project
1098 and then In_Tree
.Projects
.Table
(Data
.Extends
).Name
=
1101 return Data
.Extends
;
1104 -- Then check the name of each imported project
1106 while List
/= Empty_Project_List
loop
1107 Result
:= In_Tree
.Project_Lists
.Table
(List
).Project
;
1109 -- If the project is directly imported, then returns its ID
1112 In_Tree
.Projects
.Table
(Result
).Name
= With_Name
1117 -- If a project extending the project is imported, then keep
1118 -- this extending project as a possibility. It will be the
1119 -- returned ID if the project is not imported directly.
1122 Proj
: Project_Id
:=
1123 In_Tree
.Projects
.Table
(Result
).Extends
;
1125 while Proj
/= No_Project
loop
1126 if In_Tree
.Projects
.Table
(Proj
).Name
=
1129 Temp_Result
:= Result
;
1133 Proj
:= In_Tree
.Projects
.Table
(Proj
).Extends
;
1137 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
1141 (Temp_Result
/= No_Project
,
1142 "project not found");
1146 end Imported_Or_Extended_Project_From
;
1152 function Package_From
1153 (Project
: Project_Id
;
1154 In_Tree
: Project_Tree_Ref
;
1155 With_Name
: Name_Id
) return Package_Id
1157 Data
: constant Project_Data
:=
1158 In_Tree
.Projects
.Table
(Project
);
1159 Result
: Package_Id
:= Data
.Decl
.Packages
;
1162 -- Check the name of each existing package of Project
1164 while Result
/= No_Package
1165 and then In_Tree
.Packages
.Table
(Result
).Name
/= With_Name
1167 Result
:= In_Tree
.Packages
.Table
(Result
).Next
;
1170 if Result
= No_Package
then
1172 -- Should never happen
1174 Write_Line
("package """ & Get_Name_String
(With_Name
) &
1176 raise Program_Error
;
1188 (In_Tree
: Project_Tree_Ref
;
1189 Project
: out Project_Id
;
1190 Success
: out Boolean;
1191 From_Project_Node
: Project_Node_Id
;
1192 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1193 Report_Error
: Put_Line_Access
;
1194 Follow_Links
: Boolean := True;
1195 When_No_Sources
: Error_Warning
:= Error
;
1196 Reset_Tree
: Boolean := True)
1199 Process_Project_Tree_Phase_1
1200 (In_Tree
=> In_Tree
,
1203 From_Project_Node
=> From_Project_Node
,
1204 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1205 Report_Error
=> Report_Error
,
1206 Reset_Tree
=> Reset_Tree
);
1208 if not In_Configuration
then
1209 Process_Project_Tree_Phase_2
1210 (In_Tree
=> In_Tree
,
1213 From_Project_Node
=> From_Project_Node
,
1214 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1215 Report_Error
=> Report_Error
,
1216 Follow_Links
=> Follow_Links
,
1217 When_No_Sources
=> When_No_Sources
);
1221 -------------------------------
1222 -- Process_Declarative_Items --
1223 -------------------------------
1225 procedure Process_Declarative_Items
1226 (Project
: Project_Id
;
1227 In_Tree
: Project_Tree_Ref
;
1228 From_Project_Node
: Project_Node_Id
;
1229 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1231 Item
: Project_Node_Id
)
1233 Current_Declarative_Item
: Project_Node_Id
;
1234 Current_Item
: Project_Node_Id
;
1237 -- Loop through declarative items
1239 Current_Item
:= Empty_Node
;
1241 Current_Declarative_Item
:= Item
;
1242 while Current_Declarative_Item
/= Empty_Node
loop
1248 (Current_Declarative_Item
, From_Project_Node_Tree
);
1250 -- And set Current_Declarative_Item to the next declarative item
1251 -- ready for the next iteration.
1253 Current_Declarative_Item
:=
1254 Next_Declarative_Item
1255 (Current_Declarative_Item
, From_Project_Node_Tree
);
1257 case Kind_Of
(Current_Item
, From_Project_Node_Tree
) is
1259 when N_Package_Declaration
=>
1261 -- Do not process a package declaration that should be ignored
1263 if Expression_Kind_Of
1264 (Current_Item
, From_Project_Node_Tree
) /= Ignored
1266 -- Create the new package
1268 Package_Table
.Increment_Last
(In_Tree
.Packages
);
1271 New_Pkg
: constant Package_Id
:=
1272 Package_Table
.Last
(In_Tree
.Packages
);
1273 The_New_Package
: Package_Element
;
1275 Project_Of_Renamed_Package
:
1276 constant Project_Node_Id
:=
1277 Project_Of_Renamed_Package_Of
1278 (Current_Item
, From_Project_Node_Tree
);
1281 -- Set the name of the new package
1283 The_New_Package
.Name
:=
1284 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1286 -- Insert the new package in the appropriate list
1288 if Pkg
/= No_Package
then
1289 The_New_Package
.Next
:=
1290 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
;
1291 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
:=
1295 The_New_Package
.Next
:=
1296 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
;
1297 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
:=
1301 In_Tree
.Packages
.Table
(New_Pkg
) :=
1304 if Project_Of_Renamed_Package
/= Empty_Node
then
1309 Project_Name
: constant Name_Id
:=
1311 (Project_Of_Renamed_Package
,
1312 From_Project_Node_Tree
);
1315 constant Project_Id
:=
1316 Imported_Or_Extended_Project_From
1317 (Project
, In_Tree
, Project_Name
);
1319 Renamed_Package
: constant Package_Id
:=
1321 (Renamed_Project
, In_Tree
,
1324 From_Project_Node_Tree
));
1327 -- For a renamed package, copy the declarations of
1328 -- the renamed package, but set all the locations
1329 -- to the location of the package name in the
1330 -- renaming declaration.
1332 Copy_Package_Declarations
1334 In_Tree
.Packages
.Table
(Renamed_Package
).Decl
,
1336 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1339 (Current_Item
, From_Project_Node_Tree
),
1340 In_Tree
=> In_Tree
);
1343 -- Standard package declaration, not renaming
1346 -- Set the default values of the attributes
1350 In_Tree
.Projects
.Table
(Project
).Name
,
1352 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1355 (Current_Item
, From_Project_Node_Tree
)),
1356 Project_Level
=> False);
1358 -- And process declarative items of the new package
1360 Process_Declarative_Items
1361 (Project
=> Project
,
1363 From_Project_Node
=> From_Project_Node
,
1364 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1367 First_Declarative_Item_Of
1368 (Current_Item
, From_Project_Node_Tree
));
1373 when N_String_Type_Declaration
=>
1375 -- There is nothing to process
1379 when N_Attribute_Declaration |
1380 N_Typed_Variable_Declaration |
1381 N_Variable_Declaration
=>
1383 if Expression_Of
(Current_Item
, From_Project_Node_Tree
) =
1387 -- It must be a full associative array attribute declaration
1390 Current_Item_Name
: constant Name_Id
:=
1393 From_Project_Node_Tree
);
1394 -- The name of the attribute
1396 New_Array
: Array_Id
;
1397 -- The new associative array created
1399 Orig_Array
: Array_Id
;
1400 -- The associative array value
1402 Orig_Project_Name
: Name_Id
:= No_Name
;
1403 -- The name of the project where the associative array
1406 Orig_Project
: Project_Id
:= No_Project
;
1407 -- The id of the project where the associative array
1410 Orig_Package_Name
: Name_Id
:= No_Name
;
1411 -- The name of the package, if any, where the associative
1414 Orig_Package
: Package_Id
:= No_Package
;
1415 -- The id of the package, if any, where the associative
1418 New_Element
: Array_Element_Id
:= No_Array_Element
;
1419 -- Id of a new array element created
1421 Prev_Element
: Array_Element_Id
:= No_Array_Element
;
1422 -- Last new element id created
1424 Orig_Element
: Array_Element_Id
:= No_Array_Element
;
1425 -- Current array element in original associative array
1427 Next_Element
: Array_Element_Id
:= No_Array_Element
;
1428 -- Id of the array element that follows the new element.
1429 -- This is not always nil, because values for the
1430 -- associative array attribute may already have been
1431 -- declared, and the array elements declared are reused.
1434 -- First find if the associative array attribute already
1435 -- has elements declared.
1437 if Pkg
/= No_Package
then
1438 New_Array
:= In_Tree
.Packages
.Table
1442 New_Array
:= In_Tree
.Projects
.Table
1443 (Project
).Decl
.Arrays
;
1446 while New_Array
/= No_Array
1447 and then In_Tree
.Arrays
.Table
(New_Array
).Name
/=
1450 New_Array
:= In_Tree
.Arrays
.Table
(New_Array
).Next
;
1453 -- If the attribute has never been declared add new entry
1454 -- in the arrays of the project/package and link it.
1456 if New_Array
= No_Array
then
1457 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
1458 New_Array
:= Array_Table
.Last
(In_Tree
.Arrays
);
1460 if Pkg
/= No_Package
then
1461 In_Tree
.Arrays
.Table
(New_Array
) :=
1462 (Name
=> Current_Item_Name
,
1463 Value
=> No_Array_Element
,
1465 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
);
1467 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
:=
1471 In_Tree
.Arrays
.Table
(New_Array
) :=
1472 (Name
=> Current_Item_Name
,
1473 Value
=> No_Array_Element
,
1475 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
);
1477 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
:=
1482 -- Find the project where the value is declared
1484 Orig_Project_Name
:=
1486 (Associative_Project_Of
1487 (Current_Item
, From_Project_Node_Tree
),
1488 From_Project_Node_Tree
);
1490 for Index
in Project_Table
.First
..
1494 if In_Tree
.Projects
.Table
(Index
).Name
=
1497 Orig_Project
:= Index
;
1502 pragma Assert
(Orig_Project
/= No_Project
,
1503 "original project not found");
1505 if Associative_Package_Of
1506 (Current_Item
, From_Project_Node_Tree
) = Empty_Node
1509 In_Tree
.Projects
.Table
1510 (Orig_Project
).Decl
.Arrays
;
1513 -- If in a package, find the package where the value
1516 Orig_Package_Name
:=
1518 (Associative_Package_Of
1519 (Current_Item
, From_Project_Node_Tree
),
1520 From_Project_Node_Tree
);
1523 In_Tree
.Projects
.Table
1524 (Orig_Project
).Decl
.Packages
;
1525 pragma Assert
(Orig_Package
/= No_Package
,
1526 "original package not found");
1528 while In_Tree
.Packages
.Table
1529 (Orig_Package
).Name
/= Orig_Package_Name
1531 Orig_Package
:= In_Tree
.Packages
.Table
1532 (Orig_Package
).Next
;
1533 pragma Assert
(Orig_Package
/= No_Package
,
1534 "original package not found");
1538 In_Tree
.Packages
.Table
1539 (Orig_Package
).Decl
.Arrays
;
1542 -- Now look for the array
1544 while Orig_Array
/= No_Array
1545 and then In_Tree
.Arrays
.Table
(Orig_Array
).Name
/=
1548 Orig_Array
:= In_Tree
.Arrays
.Table
1552 if Orig_Array
= No_Array
then
1553 if Error_Report
= null then
1555 ("associative array value cannot be found",
1557 (Current_Item
, From_Project_Node_Tree
));
1560 ("associative array value cannot be found",
1566 In_Tree
.Arrays
.Table
(Orig_Array
).Value
;
1568 -- Copy each array element
1570 while Orig_Element
/= No_Array_Element
loop
1572 -- Case of first element
1574 if Prev_Element
= No_Array_Element
then
1576 -- And there is no array element declared yet,
1577 -- create a new first array element.
1579 if In_Tree
.Arrays
.Table
(New_Array
).Value
=
1582 Array_Element_Table
.Increment_Last
1583 (In_Tree
.Array_Elements
);
1584 New_Element
:= Array_Element_Table
.Last
1585 (In_Tree
.Array_Elements
);
1586 In_Tree
.Arrays
.Table
1587 (New_Array
).Value
:= New_Element
;
1588 Next_Element
:= No_Array_Element
;
1590 -- Otherwise, the new element is the first
1593 New_Element
:= In_Tree
.Arrays
.
1594 Table
(New_Array
).Value
;
1596 In_Tree
.Array_Elements
.Table
1600 -- Otherwise, reuse an existing element, or create
1601 -- one if necessary.
1605 In_Tree
.Array_Elements
.Table
1606 (Prev_Element
).Next
;
1608 if Next_Element
= No_Array_Element
then
1609 Array_Element_Table
.Increment_Last
1610 (In_Tree
.Array_Elements
);
1611 New_Element
:= Array_Element_Table
.Last
1612 (In_Tree
.Array_Elements
);
1615 New_Element
:= Next_Element
;
1617 In_Tree
.Array_Elements
.Table
1622 -- Copy the value of the element
1624 In_Tree
.Array_Elements
.Table
1626 In_Tree
.Array_Elements
.Table
1628 In_Tree
.Array_Elements
.Table
1629 (New_Element
).Value
.Project
:= Project
;
1631 -- Adjust the Next link
1633 In_Tree
.Array_Elements
.Table
1634 (New_Element
).Next
:= Next_Element
;
1636 -- Adjust the previous id for the next element
1638 Prev_Element
:= New_Element
;
1640 -- Go to the next element in the original array
1643 In_Tree
.Array_Elements
.Table
1644 (Orig_Element
).Next
;
1647 -- Make sure that the array ends here, in case there
1648 -- previously a greater number of elements.
1650 In_Tree
.Array_Elements
.Table
1651 (New_Element
).Next
:= No_Array_Element
;
1655 -- Declarations other that full associative arrays
1659 New_Value
: constant Variable_Value
:=
1661 (Project
=> Project
,
1663 From_Project_Node
=> From_Project_Node
,
1664 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1669 (Current_Item
, From_Project_Node_Tree
),
1670 From_Project_Node_Tree
),
1673 (Current_Item
, From_Project_Node_Tree
));
1674 -- The expression value
1676 The_Variable
: Variable_Id
:= No_Variable
;
1678 Current_Item_Name
: constant Name_Id
:=
1681 From_Project_Node_Tree
);
1684 -- Process a typed variable declaration
1686 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1687 N_Typed_Variable_Declaration
1689 -- Report an error for an empty string
1691 if New_Value
.Value
= Empty_String
then
1693 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1695 if Error_Report
= null then
1697 ("no value defined for %%",
1699 (Current_Item
, From_Project_Node_Tree
));
1702 ("no value defined for " &
1703 Get_Name_String
(Error_Msg_Name_1
),
1709 Current_String
: Project_Node_Id
;
1712 -- Loop through all the valid strings for the
1713 -- string type and compare to the string value.
1716 First_Literal_String
1717 (String_Type_Of
(Current_Item
,
1718 From_Project_Node_Tree
),
1719 From_Project_Node_Tree
);
1720 while Current_String
/= Empty_Node
1723 (Current_String
, From_Project_Node_Tree
) /=
1728 (Current_String
, From_Project_Node_Tree
);
1731 -- Report an error if the string value is not
1732 -- one for the string type.
1734 if Current_String
= Empty_Node
then
1735 Error_Msg_Name_1
:= New_Value
.Value
;
1738 (Current_Item
, From_Project_Node_Tree
);
1740 if Error_Report
= null then
1742 ("value %% is illegal " &
1743 "for typed string %%",
1746 From_Project_Node_Tree
));
1751 Get_Name_String
(Error_Msg_Name_1
) &
1752 """ is illegal for typed string """ &
1753 Get_Name_String
(Error_Msg_Name_2
) &
1764 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1765 N_Attribute_Declaration
1767 Associative_Array_Index_Of
1768 (Current_Item
, From_Project_Node_Tree
) = No_Name
1770 -- Case of a variable declaration or of a not
1771 -- associative array attribute.
1773 -- First, find the list where to find the variable
1776 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1777 N_Attribute_Declaration
1779 if Pkg
/= No_Package
then
1781 In_Tree
.Packages
.Table
1782 (Pkg
).Decl
.Attributes
;
1785 In_Tree
.Projects
.Table
1786 (Project
).Decl
.Attributes
;
1790 if Pkg
/= No_Package
then
1792 In_Tree
.Packages
.Table
1793 (Pkg
).Decl
.Variables
;
1796 In_Tree
.Projects
.Table
1797 (Project
).Decl
.Variables
;
1802 -- Loop through the list, to find if it has already
1805 while The_Variable
/= No_Variable
1807 In_Tree
.Variable_Elements
.Table
1808 (The_Variable
).Name
/= Current_Item_Name
1811 In_Tree
.Variable_Elements
.Table
1812 (The_Variable
).Next
;
1815 -- If it has not been declared, create a new entry
1818 if The_Variable
= No_Variable
then
1820 -- All single string attribute should already have
1821 -- been declared with a default empty string value.
1824 (Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1825 N_Attribute_Declaration
,
1826 "illegal attribute declaration");
1828 Variable_Element_Table
.Increment_Last
1829 (In_Tree
.Variable_Elements
);
1830 The_Variable
:= Variable_Element_Table
.Last
1831 (In_Tree
.Variable_Elements
);
1833 -- Put the new variable in the appropriate list
1835 if Pkg
/= No_Package
then
1836 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1838 In_Tree
.Packages
.Table
1839 (Pkg
).Decl
.Variables
,
1840 Name
=> Current_Item_Name
,
1841 Value
=> New_Value
);
1842 In_Tree
.Packages
.Table
1843 (Pkg
).Decl
.Variables
:= The_Variable
;
1846 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1848 In_Tree
.Projects
.Table
1849 (Project
).Decl
.Variables
,
1850 Name
=> Current_Item_Name
,
1851 Value
=> New_Value
);
1852 In_Tree
.Projects
.Table
1853 (Project
).Decl
.Variables
:=
1857 -- If the variable/attribute has already been
1858 -- declared, just change the value.
1861 In_Tree
.Variable_Elements
.Table
1862 (The_Variable
).Value
:=
1867 -- Associative array attribute
1870 -- Get the string index
1873 (Associative_Array_Index_Of
1874 (Current_Item
, From_Project_Node_Tree
));
1876 -- Put in lower case, if necessary
1879 (Current_Item
, From_Project_Node_Tree
)
1881 GNAT
.Case_Util
.To_Lower
1882 (Name_Buffer
(1 .. Name_Len
));
1886 The_Array
: Array_Id
;
1888 The_Array_Element
: Array_Element_Id
:=
1891 Index_Name
: constant Name_Id
:= Name_Find
;
1892 -- The name id of the index
1895 -- Look for the array in the appropriate list
1897 if Pkg
/= No_Package
then
1898 The_Array
:= In_Tree
.Packages
.Table
1902 The_Array
:= In_Tree
.Projects
.Table
1903 (Project
).Decl
.Arrays
;
1907 The_Array
/= No_Array
1908 and then In_Tree
.Arrays
.Table
1909 (The_Array
).Name
/= Current_Item_Name
1911 The_Array
:= In_Tree
.Arrays
.Table
1915 -- If the array cannot be found, create a new entry
1916 -- in the list. As The_Array_Element is initialized
1917 -- to No_Array_Element, a new element will be
1918 -- created automatically later
1920 if The_Array
= No_Array
then
1921 Array_Table
.Increment_Last
1923 The_Array
:= Array_Table
.Last
1926 if Pkg
/= No_Package
then
1927 In_Tree
.Arrays
.Table
1929 (Name
=> Current_Item_Name
,
1930 Value
=> No_Array_Element
,
1932 In_Tree
.Packages
.Table
1935 In_Tree
.Packages
.Table
1936 (Pkg
).Decl
.Arrays
:=
1940 In_Tree
.Arrays
.Table
1942 (Name
=> Current_Item_Name
,
1943 Value
=> No_Array_Element
,
1945 In_Tree
.Projects
.Table
1946 (Project
).Decl
.Arrays
);
1948 In_Tree
.Projects
.Table
1949 (Project
).Decl
.Arrays
:=
1953 -- Otherwise initialize The_Array_Element as the
1954 -- head of the element list.
1957 The_Array_Element
:=
1958 In_Tree
.Arrays
.Table
1962 -- Look in the list, if any, to find an element
1963 -- with the same index.
1965 while The_Array_Element
/= No_Array_Element
1967 In_Tree
.Array_Elements
.Table
1968 (The_Array_Element
).Index
/= Index_Name
1970 The_Array_Element
:=
1971 In_Tree
.Array_Elements
.Table
1972 (The_Array_Element
).Next
;
1975 -- If no such element were found, create a new one
1976 -- and insert it in the element list, with the
1979 if The_Array_Element
= No_Array_Element
then
1980 Array_Element_Table
.Increment_Last
1981 (In_Tree
.Array_Elements
);
1982 The_Array_Element
:= Array_Element_Table
.Last
1983 (In_Tree
.Array_Elements
);
1985 In_Tree
.Array_Elements
.Table
1986 (The_Array_Element
) :=
1987 (Index
=> Index_Name
,
1990 (Current_Item
, From_Project_Node_Tree
),
1991 Index_Case_Sensitive
=>
1992 not Case_Insensitive
1993 (Current_Item
, From_Project_Node_Tree
),
1995 Next
=> In_Tree
.Arrays
.Table
1997 In_Tree
.Arrays
.Table
1998 (The_Array
).Value
:= The_Array_Element
;
2000 -- An element with the same index already exists,
2001 -- just replace its value with the new one.
2004 In_Tree
.Array_Elements
.Table
2005 (The_Array_Element
).Value
:= New_Value
;
2012 when N_Case_Construction
=>
2014 The_Project
: Project_Id
:= Project
;
2015 -- The id of the project of the case variable
2017 The_Package
: Package_Id
:= Pkg
;
2018 -- The id of the package, if any, of the case variable
2020 The_Variable
: Variable_Value
:= Nil_Variable_Value
;
2021 -- The case variable
2023 Case_Value
: Name_Id
:= No_Name
;
2024 -- The case variable value
2026 Case_Item
: Project_Node_Id
:= Empty_Node
;
2027 Choice_String
: Project_Node_Id
:= Empty_Node
;
2028 Decl_Item
: Project_Node_Id
:= Empty_Node
;
2032 Variable_Node
: constant Project_Node_Id
:=
2033 Case_Variable_Reference_Of
2035 From_Project_Node_Tree
);
2037 Var_Id
: Variable_Id
:= No_Variable
;
2038 Name
: Name_Id
:= No_Name
;
2041 -- If a project were specified for the case variable,
2045 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2050 (Variable_Node
, From_Project_Node_Tree
),
2051 From_Project_Node_Tree
);
2053 Imported_Or_Extended_Project_From
2054 (Project
, In_Tree
, Name
);
2057 -- If a package were specified for the case variable,
2061 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2066 (Variable_Node
, From_Project_Node_Tree
),
2067 From_Project_Node_Tree
);
2069 Package_From
(The_Project
, In_Tree
, Name
);
2072 Name
:= Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2074 -- First, look for the case variable into the package,
2077 if The_Package
/= No_Package
then
2078 Var_Id
:= In_Tree
.Packages
.Table
2079 (The_Package
).Decl
.Variables
;
2081 Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2082 while Var_Id
/= No_Variable
2084 In_Tree
.Variable_Elements
.Table
2085 (Var_Id
).Name
/= Name
2087 Var_Id
:= In_Tree
.Variable_Elements
.
2088 Table
(Var_Id
).Next
;
2092 -- If not found in the package, or if there is no
2093 -- package, look at the project level.
2095 if Var_Id
= No_Variable
2098 (Variable_Node
, From_Project_Node_Tree
) = Empty_Node
2100 Var_Id
:= In_Tree
.Projects
.Table
2101 (The_Project
).Decl
.Variables
;
2102 while Var_Id
/= No_Variable
2104 In_Tree
.Variable_Elements
.Table
2105 (Var_Id
).Name
/= Name
2107 Var_Id
:= In_Tree
.Variable_Elements
.
2108 Table
(Var_Id
).Next
;
2112 if Var_Id
= No_Variable
then
2114 -- Should never happen, because this has already been
2115 -- checked during parsing.
2117 Write_Line
("variable """ &
2118 Get_Name_String
(Name
) &
2120 raise Program_Error
;
2123 -- Get the case variable
2125 The_Variable
:= In_Tree
.Variable_Elements
.
2126 Table
(Var_Id
).Value
;
2128 if The_Variable
.Kind
/= Single
then
2130 -- Should never happen, because this has already been
2131 -- checked during parsing.
2133 Write_Line
("variable""" &
2134 Get_Name_String
(Name
) &
2135 """ is not a single string variable");
2136 raise Program_Error
;
2139 -- Get the case variable value
2140 Case_Value
:= The_Variable
.Value
;
2143 -- Now look into all the case items of the case construction
2146 First_Case_Item_Of
(Current_Item
, From_Project_Node_Tree
);
2148 while Case_Item
/= Empty_Node
loop
2150 First_Choice_Of
(Case_Item
, From_Project_Node_Tree
);
2152 -- When Choice_String is nil, it means that it is
2153 -- the "when others =>" alternative.
2155 if Choice_String
= Empty_Node
then
2157 First_Declarative_Item_Of
2158 (Case_Item
, From_Project_Node_Tree
);
2159 exit Case_Item_Loop
;
2162 -- Look into all the alternative of this case item
2165 while Choice_String
/= Empty_Node
loop
2168 (Choice_String
, From_Project_Node_Tree
)
2171 First_Declarative_Item_Of
2172 (Case_Item
, From_Project_Node_Tree
);
2173 exit Case_Item_Loop
;
2178 (Choice_String
, From_Project_Node_Tree
);
2179 end loop Choice_Loop
;
2182 Next_Case_Item
(Case_Item
, From_Project_Node_Tree
);
2183 end loop Case_Item_Loop
;
2185 -- If there is an alternative, then we process it
2187 if Decl_Item
/= Empty_Node
then
2188 Process_Declarative_Items
2189 (Project
=> Project
,
2191 From_Project_Node
=> From_Project_Node
,
2192 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2200 -- Should never happen
2202 Write_Line
("Illegal declarative item: " &
2203 Project_Node_Kind
'Image
2205 (Current_Item
, From_Project_Node_Tree
)));
2206 raise Program_Error
;
2209 end Process_Declarative_Items
;
2211 ----------------------------------
2212 -- Process_Project_Tree_Phase_1 --
2213 ----------------------------------
2215 procedure Process_Project_Tree_Phase_1
2216 (In_Tree
: Project_Tree_Ref
;
2217 Project
: out Project_Id
;
2218 Success
: out Boolean;
2219 From_Project_Node
: Project_Node_Id
;
2220 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2221 Report_Error
: Put_Line_Access
;
2222 Reset_Tree
: Boolean := True)
2225 Error_Report
:= Report_Error
;
2230 -- Make sure there are no projects in the data structure
2232 Project_Table
.Set_Last
(In_Tree
.Projects
, No_Project
);
2235 Processed_Projects
.Reset
;
2237 -- And process the main project and all of the projects it depends on,
2241 (Project
=> Project
,
2243 From_Project_Node
=> From_Project_Node
,
2244 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2245 Extended_By
=> No_Project
);
2247 end Process_Project_Tree_Phase_1
;
2249 ----------------------------------
2250 -- Process_Project_Tree_Phase_2 --
2251 ----------------------------------
2253 procedure Process_Project_Tree_Phase_2
2254 (In_Tree
: Project_Tree_Ref
;
2255 Project
: Project_Id
;
2256 Success
: out Boolean;
2257 From_Project_Node
: Project_Node_Id
;
2258 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2259 Report_Error
: Put_Line_Access
;
2260 Follow_Links
: Boolean := True;
2261 When_No_Sources
: Error_Warning
:= Error
)
2263 Obj_Dir
: Path_Name_Type
;
2264 Extending
: Project_Id
;
2265 Extending2
: Project_Id
;
2267 -- Start of processing for Process_Project_Tree_Phase_2
2270 Error_Report
:= Report_Error
;
2273 if Project
/= No_Project
then
2275 (In_Tree
, Project
, Follow_Links
, When_No_Sources
);
2278 -- If main project is an extending all project, set the object
2279 -- directory of all virtual extending projects to the object
2280 -- directory of the main project.
2282 if Project
/= No_Project
2284 Is_Extending_All
(From_Project_Node
, From_Project_Node_Tree
)
2287 Object_Dir
: constant Path_Name_Type
:=
2288 In_Tree
.Projects
.Table
2289 (Project
).Object_Directory
;
2292 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
2294 if In_Tree
.Projects
.Table
(Index
).Virtual
then
2295 In_Tree
.Projects
.Table
(Index
).Object_Directory
:=
2302 -- Check that no extending project shares its object directory with
2303 -- the project(s) it extends.
2305 if Project
/= No_Project
then
2307 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
2309 Extending
:= In_Tree
.Projects
.Table
(Proj
).Extended_By
;
2311 if Extending
/= No_Project
then
2312 Obj_Dir
:= In_Tree
.Projects
.Table
(Proj
).Object_Directory
;
2314 -- Check that a project being extended does not share its
2315 -- object directory with any project that extends it, directly
2316 -- or indirectly, including a virtual extending project.
2318 -- Start with the project directly extending it
2320 Extending2
:= Extending
;
2321 while Extending2
/= No_Project
loop
2322 if In_Tree
.Projects
.Table
(Extending2
).Ada_Sources
/=
2325 In_Tree
.Projects
.Table
(Extending2
).Object_Directory
=
2328 if In_Tree
.Projects
.Table
(Extending2
).Virtual
then
2330 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
2332 if Error_Report
= null then
2334 ("project %% cannot be extended by a virtual" &
2335 " project with the same object directory",
2336 In_Tree
.Projects
.Table
(Proj
).Location
);
2340 Get_Name_String
(Error_Msg_Name_1
) &
2341 """ cannot be extended by a virtual " &
2342 "project with the same object directory",
2348 In_Tree
.Projects
.Table
(Extending2
).Display_Name
;
2350 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
2352 if Error_Report
= null then
2354 ("project %% cannot extend project %%",
2355 In_Tree
.Projects
.Table
(Extending2
).Location
);
2357 ("\they share the same object directory",
2358 In_Tree
.Projects
.Table
(Extending2
).Location
);
2363 Get_Name_String
(Error_Msg_Name_1
) &
2364 """ cannot extend project """ &
2365 Get_Name_String
(Error_Msg_Name_2
) & """",
2368 ("they share the same object directory",
2374 -- Continue with the next extending project, if any
2377 In_Tree
.Projects
.Table
(Extending2
).Extended_By
;
2384 Total_Errors_Detected
= 0
2386 (Warning_Mode
/= Treat_As_Error
or else Warnings_Detected
= 0);
2387 end Process_Project_Tree_Phase_2
;
2389 ---------------------
2390 -- Recursive_Check --
2391 ---------------------
2393 procedure Recursive_Check
2394 (Project
: Project_Id
;
2395 In_Tree
: Project_Tree_Ref
;
2396 Follow_Links
: Boolean;
2397 When_No_Sources
: Error_Warning
)
2399 Data
: Project_Data
;
2400 Imported_Project_List
: Project_List
:= Empty_Project_List
;
2403 -- Do nothing if Project is No_Project, or Project has already
2404 -- been marked as checked.
2406 if Project
/= No_Project
2407 and then not In_Tree
.Projects
.Table
(Project
).Checked
2409 -- Mark project as checked, to avoid infinite recursion in
2410 -- ill-formed trees, where a project imports itself.
2412 In_Tree
.Projects
.Table
(Project
).Checked
:= True;
2414 Data
:= In_Tree
.Projects
.Table
(Project
);
2416 -- Call itself for a possible extended project.
2417 -- (if there is no extended project, then nothing happens).
2420 (Data
.Extends
, In_Tree
, Follow_Links
, When_No_Sources
);
2422 -- Call itself for all imported projects
2424 Imported_Project_List
:= Data
.Imported_Projects
;
2425 while Imported_Project_List
/= Empty_Project_List
loop
2427 (In_Tree
.Project_Lists
.Table
2428 (Imported_Project_List
).Project
,
2429 In_Tree
, Follow_Links
, When_No_Sources
);
2430 Imported_Project_List
:=
2431 In_Tree
.Project_Lists
.Table
2432 (Imported_Project_List
).Next
;
2435 if Verbose_Mode
then
2436 Write_Str
("Checking project file """);
2437 Write_Str
(Get_Name_String
(Data
.Name
));
2442 (Project
, In_Tree
, Error_Report
, Follow_Links
, When_No_Sources
);
2444 end Recursive_Check
;
2446 -----------------------
2447 -- Recursive_Process --
2448 -----------------------
2450 procedure Recursive_Process
2451 (In_Tree
: Project_Tree_Ref
;
2452 Project
: out Project_Id
;
2453 From_Project_Node
: Project_Node_Id
;
2454 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2455 Extended_By
: Project_Id
)
2457 With_Clause
: Project_Node_Id
;
2460 if From_Project_Node
= Empty_Node
then
2461 Project
:= No_Project
;
2465 Processed_Data
: Project_Data
:= Empty_Project
(In_Tree
);
2466 Imported
: Project_List
:= Empty_Project_List
;
2467 Declaration_Node
: Project_Node_Id
:= Empty_Node
;
2468 Tref
: Source_Buffer_Ptr
;
2469 Name
: constant Name_Id
:=
2471 (From_Project_Node
, From_Project_Node_Tree
);
2472 Location
: Source_Ptr
:=
2474 (From_Project_Node
, From_Project_Node_Tree
);
2477 Project
:= Processed_Projects
.Get
(Name
);
2479 if Project
/= No_Project
then
2481 -- Make sure that, when a project is extended, the project id
2482 -- of the project extending it is recorded in its data, even
2483 -- when it has already been processed as an imported project.
2484 -- This is for virtually extended projects.
2486 if Extended_By
/= No_Project
then
2487 In_Tree
.Projects
.Table
(Project
).Extended_By
:= Extended_By
;
2493 Project_Table
.Increment_Last
(In_Tree
.Projects
);
2494 Project
:= Project_Table
.Last
(In_Tree
.Projects
);
2495 Processed_Projects
.Set
(Name
, Project
);
2497 Processed_Data
.Name
:= Name
;
2499 Get_Name_String
(Name
);
2501 -- If name starts with the virtual prefix, flag the project as
2502 -- being a virtual extending project.
2504 if Name_Len
> Virtual_Prefix
'Length
2505 and then Name_Buffer
(1 .. Virtual_Prefix
'Length) =
2508 Processed_Data
.Virtual
:= True;
2509 Processed_Data
.Display_Name
:= Name
;
2511 -- If there is no file, for example when the project node tree is
2512 -- built in memory by GPS, the Display_Name cannot be found in
2513 -- the source, so its value is the same as Name.
2515 elsif Location
= No_Location
then
2516 Processed_Data
.Display_Name
:= Name
;
2518 -- Get the spelling of the project name from the project file
2521 Tref
:= Source_Text
(Get_Source_File_Index
(Location
));
2523 for J
in 1 .. Name_Len
loop
2524 Name_Buffer
(J
) := Tref
(Location
);
2525 Location
:= Location
+ 1;
2528 Processed_Data
.Display_Name
:= Name_Find
;
2531 Processed_Data
.Display_Path_Name
:=
2532 Path_Name_Of
(From_Project_Node
, From_Project_Node_Tree
);
2533 Get_Name_String
(Processed_Data
.Display_Path_Name
);
2534 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2535 Processed_Data
.Path_Name
:= Name_Find
;
2537 Processed_Data
.Location
:=
2538 Location_Of
(From_Project_Node
, From_Project_Node_Tree
);
2540 Processed_Data
.Display_Directory
:=
2541 Directory_Of
(From_Project_Node
, From_Project_Node_Tree
);
2542 Get_Name_String
(Processed_Data
.Display_Directory
);
2543 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2544 Processed_Data
.Directory
:= Name_Find
;
2546 Processed_Data
.Extended_By
:= Extended_By
;
2552 Processed_Data
.Decl
,
2553 Prj
.Attr
.Attribute_First
,
2554 Project_Level
=> True);
2557 First_With_Clause_Of
(From_Project_Node
, From_Project_Node_Tree
);
2558 while With_Clause
/= Empty_Node
loop
2560 New_Project
: Project_Id
;
2561 New_Data
: Project_Data
;
2565 (In_Tree
=> In_Tree
,
2566 Project
=> New_Project
,
2567 From_Project_Node
=>
2568 Project_Node_Of
(With_Clause
, From_Project_Node_Tree
),
2569 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2570 Extended_By
=> No_Project
);
2572 In_Tree
.Projects
.Table
(New_Project
);
2574 -- If we were the first project to import it,
2575 -- set First_Referred_By to us.
2577 if New_Data
.First_Referred_By
= No_Project
then
2578 New_Data
.First_Referred_By
:= Project
;
2579 In_Tree
.Projects
.Table
(New_Project
) :=
2583 -- Add this project to our list of imported projects
2585 Project_List_Table
.Increment_Last
2586 (In_Tree
.Project_Lists
);
2587 In_Tree
.Project_Lists
.Table
2588 (Project_List_Table
.Last
2589 (In_Tree
.Project_Lists
)) :=
2590 (Project
=> New_Project
, Next
=> Empty_Project_List
);
2592 -- Imported is the id of the last imported project.
2593 -- If it is nil, then this imported project is our first.
2595 if Imported
= Empty_Project_List
then
2596 Processed_Data
.Imported_Projects
:=
2597 Project_List_Table
.Last
2598 (In_Tree
.Project_Lists
);
2601 In_Tree
.Project_Lists
.Table
2602 (Imported
).Next
:= Project_List_Table
.Last
2603 (In_Tree
.Project_Lists
);
2606 Imported
:= Project_List_Table
.Last
2607 (In_Tree
.Project_Lists
);
2610 Next_With_Clause_Of
(With_Clause
, From_Project_Node_Tree
);
2615 Project_Declaration_Of
2616 (From_Project_Node
, From_Project_Node_Tree
);
2619 (In_Tree
=> In_Tree
,
2620 Project
=> Processed_Data
.Extends
,
2621 From_Project_Node
=> Extended_Project_Of
2623 From_Project_Node_Tree
),
2624 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2625 Extended_By
=> Project
);
2627 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2629 Process_Declarative_Items
2630 (Project
=> Project
,
2632 From_Project_Node
=> From_Project_Node
,
2633 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2635 Item
=> First_Declarative_Item_Of
2637 From_Project_Node_Tree
));
2639 -- If it is an extending project, inherit all packages
2640 -- from the extended project that are not explicitely defined
2641 -- or renamed. Also inherit the languages, if attribute Languages
2642 -- is not explicitely defined.
2644 if Processed_Data
.Extends
/= No_Project
then
2645 Processed_Data
:= In_Tree
.Projects
.Table
(Project
);
2648 Extended_Pkg
: Package_Id
;
2649 Current_Pkg
: Package_Id
;
2650 Element
: Package_Element
;
2651 First
: constant Package_Id
:=
2652 Processed_Data
.Decl
.Packages
;
2653 Attribute1
: Variable_Id
;
2654 Attribute2
: Variable_Id
;
2655 Attr_Value1
: Variable
;
2656 Attr_Value2
: Variable
;
2660 In_Tree
.Projects
.Table
2661 (Processed_Data
.Extends
).Decl
.Packages
;
2662 while Extended_Pkg
/= No_Package
loop
2664 In_Tree
.Packages
.Table
(Extended_Pkg
);
2666 Current_Pkg
:= First
;
2667 while Current_Pkg
/= No_Package
2668 and then In_Tree
.Packages
.Table
(Current_Pkg
).Name
/=
2672 In_Tree
.Packages
.Table
(Current_Pkg
).Next
;
2675 if Current_Pkg
= No_Package
then
2676 Package_Table
.Increment_Last
2678 Current_Pkg
:= Package_Table
.Last
(In_Tree
.Packages
);
2679 In_Tree
.Packages
.Table
(Current_Pkg
) :=
2680 (Name
=> Element
.Name
,
2681 Decl
=> No_Declarations
,
2682 Parent
=> No_Package
,
2683 Next
=> Processed_Data
.Decl
.Packages
);
2684 Processed_Data
.Decl
.Packages
:= Current_Pkg
;
2685 Copy_Package_Declarations
2686 (From
=> Element
.Decl
,
2687 To
=> In_Tree
.Packages
.Table
(Current_Pkg
).Decl
,
2688 New_Loc
=> No_Location
,
2689 In_Tree
=> In_Tree
);
2692 Extended_Pkg
:= Element
.Next
;
2695 -- Check if attribute Languages is declared in the
2696 -- extending project.
2698 Attribute1
:= Processed_Data
.Decl
.Attributes
;
2699 while Attribute1
/= No_Variable
loop
2700 Attr_Value1
:= In_Tree
.Variable_Elements
.
2702 exit when Attr_Value1
.Name
= Snames
.Name_Languages
;
2703 Attribute1
:= Attr_Value1
.Next
;
2706 if Attribute1
= No_Variable
or else
2707 Attr_Value1
.Value
.Default
2709 -- Attribute Languages is not declared in the extending
2710 -- project. Check if it is declared in the project being
2714 In_Tree
.Projects
.Table
2715 (Processed_Data
.Extends
).Decl
.Attributes
;
2716 while Attribute2
/= No_Variable
loop
2717 Attr_Value2
:= In_Tree
.Variable_Elements
.
2719 exit when Attr_Value2
.Name
= Snames
.Name_Languages
;
2720 Attribute2
:= Attr_Value2
.Next
;
2723 if Attribute2
/= No_Variable
and then
2724 not Attr_Value2
.Value
.Default
2726 -- As attribute Languages is declared in the project
2727 -- being extended, copy its value for the extending
2730 if Attribute1
= No_Variable
then
2731 Variable_Element_Table
.Increment_Last
2732 (In_Tree
.Variable_Elements
);
2733 Attribute1
:= Variable_Element_Table
.Last
2734 (In_Tree
.Variable_Elements
);
2735 Attr_Value1
.Next
:= Processed_Data
.Decl
.Attributes
;
2736 Processed_Data
.Decl
.Attributes
:= Attribute1
;
2739 Attr_Value1
.Name
:= Snames
.Name_Languages
;
2740 Attr_Value1
.Value
:= Attr_Value2
.Value
;
2741 In_Tree
.Variable_Elements
.Table
2742 (Attribute1
) := Attr_Value1
;
2747 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2751 end Recursive_Process
;