Add hppa-openbsd target
[official-gcc.git] / gcc / ada / prj-proc.adb
blob095603084a022cafeba828dd38d7ed2d6a8d2f57
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . P R O C --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 2001-2002 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, 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 COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- GNAT was originally developed by the GNAT team at New York University. --
24 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
25 -- --
26 ------------------------------------------------------------------------------
28 with Errout; use Errout;
29 with Namet; use Namet;
30 with Opt;
31 with Output; use Output;
32 with Prj.Attr; use Prj.Attr;
33 with Prj.Com; use Prj.Com;
34 with Prj.Ext; use Prj.Ext;
35 with Prj.Nmsc; use Prj.Nmsc;
36 with Stringt; use Stringt;
38 with GNAT.Case_Util; use GNAT.Case_Util;
39 with GNAT.HTable;
41 package body Prj.Proc is
43 Error_Report : Put_Line_Access := null;
45 package Processed_Projects is new GNAT.HTable.Simple_HTable
46 (Header_Num => Header_Num,
47 Element => Project_Id,
48 No_Element => No_Project,
49 Key => Name_Id,
50 Hash => Hash,
51 Equal => "=");
52 -- This hash table contains all processed projects
54 procedure Add (To_Exp : in out String_Id; Str : String_Id);
55 -- Concatenate two strings and returns another string if both
56 -- arguments are not null string.
58 procedure Add_Attributes
59 (Decl : in out Declarations;
60 First : Attribute_Node_Id);
61 -- Add all attributes, starting with First, with their default
62 -- values to the package or project with declarations Decl.
64 function Expression
65 (Project : Project_Id;
66 From_Project_Node : Project_Node_Id;
67 Pkg : Package_Id;
68 First_Term : Project_Node_Id;
69 Kind : Variable_Kind)
70 return Variable_Value;
71 -- From N_Expression project node From_Project_Node, compute the value
72 -- of an expression and return it as a Variable_Value.
74 function Imported_Or_Modified_Project_From
75 (Project : Project_Id;
76 With_Name : Name_Id)
77 return Project_Id;
78 -- Find an imported or modified project of Project whose name is With_Name
80 function Package_From
81 (Project : Project_Id;
82 With_Name : Name_Id)
83 return Package_Id;
84 -- Find the package of Project whose name is With_Name
86 procedure Process_Declarative_Items
87 (Project : Project_Id;
88 From_Project_Node : Project_Node_Id;
89 Pkg : Package_Id;
90 Item : Project_Node_Id);
91 -- Process declarative items starting with From_Project_Node, and put them
92 -- in declarations Decl. This is a recursive procedure; it calls itself for
93 -- a package declaration or a case construction.
95 procedure Recursive_Process
96 (Project : out Project_Id;
97 From_Project_Node : Project_Node_Id;
98 Modified_By : Project_Id);
99 -- Process project with node From_Project_Node in the tree.
100 -- Do nothing if From_Project_Node is Empty_Node.
101 -- If project has already been processed, simply return its project id.
102 -- Otherwise create a new project id, mark it as processed, call itself
103 -- recursively for all imported projects and a modified project, if any.
104 -- Then process the declarative items of the project.
106 procedure Check (Project : in out Project_Id);
107 -- Set all projects to not checked, then call Recursive_Check for the
108 -- main project Project. Project is set to No_Project if errors occurred.
110 procedure Recursive_Check (Project : Project_Id);
111 -- If Project is marked as not checked, mark it as checked, call
112 -- Check_Naming_Scheme for the project, then call itself for a
113 -- possible modified project and all the imported projects of Project.
115 ---------
116 -- Add --
117 ---------
119 procedure Add (To_Exp : in out String_Id; Str : String_Id) is
120 begin
121 if To_Exp = Types.No_String or else String_Length (To_Exp) = 0 then
123 -- To_Exp is nil or empty. The result is Str.
125 To_Exp := Str;
127 -- If Str is nil, then do not change To_Ext
129 elsif Str /= No_String then
130 Start_String (To_Exp);
131 Store_String_Chars (Str);
132 To_Exp := End_String;
133 end if;
134 end Add;
136 --------------------
137 -- Add_Attributes --
138 --------------------
140 procedure Add_Attributes
141 (Decl : in out Declarations;
142 First : Attribute_Node_Id) is
143 The_Attribute : Attribute_Node_Id := First;
144 Attribute_Data : Attribute_Record;
146 begin
147 while The_Attribute /= Empty_Attribute loop
148 Attribute_Data := Attributes.Table (The_Attribute);
150 if Attribute_Data.Kind_2 /= Associative_Array then
151 declare
152 New_Attribute : Variable_Value;
154 begin
155 case Attribute_Data.Kind_1 is
157 -- Undefined should not happen
159 when Undefined =>
160 pragma Assert
161 (False, "attribute with an undefined kind");
162 raise Program_Error;
164 -- Single attributes have a default value of empty string
166 when Single =>
167 New_Attribute :=
168 (Kind => Single,
169 Location => No_Location,
170 Default => True,
171 Value => Empty_String);
173 -- List attributes have a default value of nil list
175 when List =>
176 New_Attribute :=
177 (Kind => List,
178 Location => No_Location,
179 Default => True,
180 Values => Nil_String);
182 end case;
184 Variable_Elements.Increment_Last;
185 Variable_Elements.Table (Variable_Elements.Last) :=
186 (Next => Decl.Attributes,
187 Name => Attribute_Data.Name,
188 Value => New_Attribute);
189 Decl.Attributes := Variable_Elements.Last;
190 end;
191 end if;
193 The_Attribute := Attributes.Table (The_Attribute).Next;
194 end loop;
196 end Add_Attributes;
198 -----------
199 -- Check --
200 -----------
202 procedure Check (Project : in out Project_Id) is
203 begin
204 -- Make sure that all projects are marked as not checked
206 for Index in 1 .. Projects.Last loop
207 Projects.Table (Index).Checked := False;
208 end loop;
210 Recursive_Check (Project);
212 if Errout.Total_Errors_Detected > 0 then
213 Project := No_Project;
214 end if;
216 end Check;
218 ----------------
219 -- Expression --
220 ----------------
222 function Expression
223 (Project : Project_Id;
224 From_Project_Node : Project_Node_Id;
225 Pkg : Package_Id;
226 First_Term : Project_Node_Id;
227 Kind : Variable_Kind)
228 return Variable_Value
230 The_Term : Project_Node_Id := First_Term;
231 -- The term in the expression list
233 The_Current_Term : Project_Node_Id := Empty_Node;
234 -- The current term node id
236 Term_Kind : Variable_Kind;
237 -- The kind of the current term
239 Result : Variable_Value (Kind => Kind);
240 -- The returned result
242 Last : String_List_Id := Nil_String;
243 -- Reference to the last string elements in Result, when Kind is List.
245 begin
246 Result.Location := Location_Of (First_Term);
248 -- Process each term of the expression, starting with First_Term
250 while The_Term /= Empty_Node loop
252 -- We get the term data and kind ...
254 Term_Kind := Expression_Kind_Of (The_Term);
256 The_Current_Term := Current_Term (The_Term);
258 case Kind_Of (The_Current_Term) is
260 when N_Literal_String =>
262 case Kind is
264 when Undefined =>
266 -- Should never happen
268 pragma Assert (False, "Undefined expression kind");
269 raise Program_Error;
271 when Single =>
272 Add (Result.Value, String_Value_Of (The_Current_Term));
274 when List =>
276 String_Elements.Increment_Last;
278 if Last = Nil_String then
280 -- This can happen in an expression such as
281 -- () & "toto"
283 Result.Values := String_Elements.Last;
285 else
286 String_Elements.Table (Last).Next :=
287 String_Elements.Last;
288 end if;
290 Last := String_Elements.Last;
291 String_Elements.Table (Last) :=
292 (Value => String_Value_Of (The_Current_Term),
293 Location => Location_Of (The_Current_Term),
294 Next => Nil_String);
296 end case;
298 when N_Literal_String_List =>
300 declare
301 String_Node : Project_Node_Id :=
302 First_Expression_In_List (The_Current_Term);
304 Value : Variable_Value;
306 begin
307 if String_Node /= Empty_Node then
309 -- If String_Node is nil, it is an empty list,
310 -- there is nothing to do
312 Value := Expression
313 (Project => Project,
314 From_Project_Node => From_Project_Node,
315 Pkg => Pkg,
316 First_Term => Tree.First_Term (String_Node),
317 Kind => Single);
318 String_Elements.Increment_Last;
320 if Result.Values = Nil_String then
322 -- This literal string list is the first term
323 -- in a string list expression
325 Result.Values := String_Elements.Last;
327 else
328 String_Elements.Table (Last).Next :=
329 String_Elements.Last;
330 end if;
332 Last := String_Elements.Last;
333 String_Elements.Table (Last) :=
334 (Value => Value.Value,
335 Location => Value.Location,
336 Next => Nil_String);
338 loop
339 -- Add the other element of the literal string list
340 -- one after the other
342 String_Node :=
343 Next_Expression_In_List (String_Node);
345 exit when String_Node = Empty_Node;
347 Value :=
348 Expression
349 (Project => Project,
350 From_Project_Node => From_Project_Node,
351 Pkg => Pkg,
352 First_Term => Tree.First_Term (String_Node),
353 Kind => Single);
355 String_Elements.Increment_Last;
356 String_Elements.Table (Last).Next :=
357 String_Elements.Last;
358 Last := String_Elements.Last;
359 String_Elements.Table (Last) :=
360 (Value => Value.Value,
361 Location => Value.Location,
362 Next => Nil_String);
363 end loop;
365 end if;
367 end;
369 when N_Variable_Reference | N_Attribute_Reference =>
371 declare
372 The_Project : Project_Id := Project;
373 The_Package : Package_Id := Pkg;
374 The_Name : Name_Id := No_Name;
375 The_Variable_Id : Variable_Id := No_Variable;
376 The_Variable : Variable_Value;
377 Term_Project : constant Project_Node_Id :=
378 Project_Node_Of (The_Current_Term);
379 Term_Package : constant Project_Node_Id :=
380 Package_Node_Of (The_Current_Term);
381 Index : String_Id := No_String;
383 begin
384 if Term_Project /= Empty_Node and then
385 Term_Project /= From_Project_Node
386 then
387 -- This variable or attribute comes from another project
389 The_Name := Name_Of (Term_Project);
390 The_Project := Imported_Or_Modified_Project_From
391 (Project => Project, With_Name => The_Name);
392 end if;
394 if Term_Package /= Empty_Node then
396 -- This is an attribute of a package
398 The_Name := Name_Of (Term_Package);
399 The_Package := Projects.Table (The_Project).Decl.Packages;
401 while The_Package /= No_Package
402 and then Packages.Table (The_Package).Name /= The_Name
403 loop
404 The_Package := Packages.Table (The_Package).Next;
405 end loop;
407 pragma Assert
408 (The_Package /= No_Package,
409 "package not found.");
411 elsif Kind_Of (The_Current_Term) = N_Attribute_Reference then
412 The_Package := No_Package;
413 end if;
415 The_Name := Name_Of (The_Current_Term);
417 if Kind_Of (The_Current_Term) = N_Attribute_Reference then
418 Index := Associative_Array_Index_Of (The_Current_Term);
419 end if;
421 -- If it is not an associative array attribute
423 if Index = No_String then
425 -- It is not an associative array attribute
427 if The_Package /= No_Package then
429 -- First, if there is a package, look into the package
432 Kind_Of (The_Current_Term) = N_Variable_Reference
433 then
434 The_Variable_Id :=
435 Packages.Table (The_Package).Decl.Variables;
437 else
438 The_Variable_Id :=
439 Packages.Table (The_Package).Decl.Attributes;
440 end if;
442 while The_Variable_Id /= No_Variable
443 and then
444 Variable_Elements.Table (The_Variable_Id).Name /=
445 The_Name
446 loop
447 The_Variable_Id :=
448 Variable_Elements.Table (The_Variable_Id).Next;
449 end loop;
451 end if;
453 if The_Variable_Id = No_Variable then
455 -- If we have not found it, look into the project
458 Kind_Of (The_Current_Term) = N_Variable_Reference
459 then
460 The_Variable_Id :=
461 Projects.Table (The_Project).Decl.Variables;
463 else
464 The_Variable_Id :=
465 Projects.Table (The_Project).Decl.Attributes;
466 end if;
468 while The_Variable_Id /= No_Variable
469 and then
470 Variable_Elements.Table (The_Variable_Id).Name /=
471 The_Name
472 loop
473 The_Variable_Id :=
474 Variable_Elements.Table (The_Variable_Id).Next;
475 end loop;
477 end if;
479 pragma Assert (The_Variable_Id /= No_Variable,
480 "variable or attribute not found");
482 The_Variable := Variable_Elements.Table
483 (The_Variable_Id).Value;
485 else
487 -- It is an associative array attribute
489 declare
490 The_Array : Array_Id := No_Array;
491 The_Element : Array_Element_Id := No_Array_Element;
492 Array_Index : Name_Id := No_Name;
493 begin
494 if The_Package /= No_Package then
495 The_Array :=
496 Packages.Table (The_Package).Decl.Arrays;
498 else
499 The_Array :=
500 Projects.Table (The_Project).Decl.Arrays;
501 end if;
503 while The_Array /= No_Array
504 and then Arrays.Table (The_Array).Name /= The_Name
505 loop
506 The_Array := Arrays.Table (The_Array).Next;
507 end loop;
509 if The_Array /= No_Array then
510 The_Element := Arrays.Table (The_Array).Value;
512 String_To_Name_Buffer (Index);
514 if Case_Insensitive (The_Current_Term) then
515 To_Lower (Name_Buffer (1 .. Name_Len));
516 end if;
518 Array_Index := Name_Find;
520 while The_Element /= No_Array_Element
521 and then Array_Elements.Table (The_Element).Index
522 /= Array_Index
523 loop
524 The_Element :=
525 Array_Elements.Table (The_Element).Next;
526 end loop;
528 end if;
530 if The_Element /= No_Array_Element then
531 The_Variable :=
532 Array_Elements.Table (The_Element).Value;
534 else
536 Expression_Kind_Of (The_Current_Term) = List
537 then
538 The_Variable :=
539 (Kind => List,
540 Location => No_Location,
541 Default => True,
542 Values => Nil_String);
544 else
545 The_Variable :=
546 (Kind => Single,
547 Location => No_Location,
548 Default => True,
549 Value => Empty_String);
550 end if;
552 end if;
554 end;
556 end if;
558 case Kind is
560 when Undefined =>
562 -- Should never happen
564 pragma Assert (False, "undefined expression kind");
565 null;
567 when Single =>
569 case The_Variable.Kind is
571 when Undefined =>
572 null;
574 when Single =>
575 Add (Result.Value, The_Variable.Value);
577 when List =>
579 -- Should never happen
581 pragma Assert
582 (False,
583 "list cannot appear in single " &
584 "string expression");
585 null;
587 end case;
589 when List =>
590 case The_Variable.Kind is
592 when Undefined =>
593 null;
595 when Single =>
596 String_Elements.Increment_Last;
598 if Last = Nil_String then
600 -- This can happen in an expression such as
601 -- () & Var
603 Result.Values := String_Elements.Last;
605 else
606 String_Elements.Table (Last).Next :=
607 String_Elements.Last;
608 end if;
610 Last := String_Elements.Last;
611 String_Elements.Table (Last) :=
612 (Value => The_Variable.Value,
613 Location => Location_Of (The_Current_Term),
614 Next => Nil_String);
616 when List =>
618 declare
619 The_List : String_List_Id :=
620 The_Variable.Values;
622 begin
623 while The_List /= Nil_String loop
624 String_Elements.Increment_Last;
626 if Last = Nil_String then
627 Result.Values := String_Elements.Last;
629 else
630 String_Elements.Table (Last).Next :=
631 String_Elements.Last;
633 end if;
635 Last := String_Elements.Last;
636 String_Elements.Table (Last) :=
637 (Value =>
638 String_Elements.Table
639 (The_List).Value,
640 Location => Location_Of
641 (The_Current_Term),
642 Next => Nil_String);
643 The_List :=
644 String_Elements.Table (The_List).Next;
646 end loop;
647 end;
648 end case;
649 end case;
650 end;
652 when N_External_Value =>
653 String_To_Name_Buffer
654 (String_Value_Of (External_Reference_Of (The_Current_Term)));
656 declare
657 Name : constant Name_Id := Name_Find;
658 Default : String_Id := No_String;
659 Value : String_Id := No_String;
661 Default_Node : constant Project_Node_Id :=
662 External_Default_Of (The_Current_Term);
664 begin
665 if Default_Node /= Empty_Node then
666 Default := String_Value_Of (Default_Node);
667 end if;
669 Value := Prj.Ext.Value_Of (Name, Default);
671 if Value = No_String then
672 if Error_Report = null then
673 Error_Msg
674 ("undefined external reference",
675 Location_Of (The_Current_Term));
677 else
678 Error_Report
679 ("""" & Get_Name_String (Name) &
680 """ is an undefined external reference",
681 Project);
682 end if;
684 Value := Empty_String;
686 end if;
688 case Kind is
690 when Undefined =>
691 null;
693 when Single =>
694 Add (Result.Value, Value);
696 when List =>
697 String_Elements.Increment_Last;
699 if Last = Nil_String then
700 Result.Values := String_Elements.Last;
702 else
703 String_Elements.Table (Last).Next :=
704 String_Elements.Last;
705 end if;
707 Last := String_Elements.Last;
708 String_Elements.Table (Last) :=
709 (Value => Value,
710 Location => Location_Of (The_Current_Term),
711 Next => Nil_String);
713 end case;
715 end;
717 when others =>
719 -- Should never happen
721 pragma Assert
722 (False,
723 "illegal node kind in an expression");
724 raise Program_Error;
726 end case;
728 The_Term := Next_Term (The_Term);
729 end loop;
731 return Result;
732 end Expression;
734 ---------------------------------------
735 -- Imported_Or_Modified_Project_From --
736 ---------------------------------------
738 function Imported_Or_Modified_Project_From
739 (Project : Project_Id;
740 With_Name : Name_Id)
741 return Project_Id
743 Data : constant Project_Data := Projects.Table (Project);
744 List : Project_List := Data.Imported_Projects;
746 begin
747 -- First check if it is the name of a modified project
749 if Data.Modifies /= No_Project
750 and then Projects.Table (Data.Modifies).Name = With_Name
751 then
752 return Data.Modifies;
754 else
755 -- Then check the name of each imported project
757 while List /= Empty_Project_List
758 and then
759 Projects.Table
760 (Project_Lists.Table (List).Project).Name /= With_Name
762 loop
763 List := Project_Lists.Table (List).Next;
764 end loop;
766 pragma Assert
767 (List /= Empty_Project_List,
768 "project not found");
770 return Project_Lists.Table (List).Project;
771 end if;
772 end Imported_Or_Modified_Project_From;
774 ------------------
775 -- Package_From --
776 ------------------
778 function Package_From
779 (Project : Project_Id;
780 With_Name : Name_Id)
781 return Package_Id
783 Data : constant Project_Data := Projects.Table (Project);
784 Result : Package_Id := Data.Decl.Packages;
786 begin
787 -- Check the name of each existing package of Project
789 while Result /= No_Package
790 and then
791 Packages.Table (Result).Name /= With_Name
792 loop
793 Result := Packages.Table (Result).Next;
794 end loop;
796 if Result = No_Package then
797 -- Should never happen
798 Write_Line ("package """ & Get_Name_String (With_Name) &
799 """ not found");
800 raise Program_Error;
802 else
803 return Result;
804 end if;
805 end Package_From;
807 -------------
808 -- Process --
809 -------------
811 procedure Process
812 (Project : out Project_Id;
813 From_Project_Node : Project_Node_Id;
814 Report_Error : Put_Line_Access)
816 begin
817 Error_Report := Report_Error;
819 -- Make sure there is no projects in the data structure
821 Projects.Set_Last (No_Project);
822 Processed_Projects.Reset;
824 -- And process the main project and all of the projects it depends on,
825 -- recursively
827 Recursive_Process
828 (Project => Project,
829 From_Project_Node => From_Project_Node,
830 Modified_By => No_Project);
832 if Errout.Total_Errors_Detected > 0 then
833 Project := No_Project;
834 end if;
836 if Project /= No_Project then
837 Check (Project);
838 end if;
839 end Process;
841 -------------------------------
842 -- Process_Declarative_Items --
843 -------------------------------
845 procedure Process_Declarative_Items
846 (Project : Project_Id;
847 From_Project_Node : Project_Node_Id;
848 Pkg : Package_Id;
849 Item : Project_Node_Id) is
851 Current_Declarative_Item : Project_Node_Id := Item;
853 Current_Item : Project_Node_Id := Empty_Node;
855 begin
856 -- For each declarative item
858 while Current_Declarative_Item /= Empty_Node loop
860 -- Get its data
862 Current_Item := Current_Item_Node (Current_Declarative_Item);
864 -- And set Current_Declarative_Item to the next declarative item
865 -- ready for the next iteration
867 Current_Declarative_Item := Next_Declarative_Item
868 (Current_Declarative_Item);
870 case Kind_Of (Current_Item) is
872 when N_Package_Declaration =>
873 Packages.Increment_Last;
875 declare
876 New_Pkg : constant Package_Id := Packages.Last;
877 The_New_Package : Package_Element;
879 Project_Of_Renamed_Package : constant Project_Node_Id :=
880 Project_Of_Renamed_Package_Of
881 (Current_Item);
883 begin
884 The_New_Package.Name := Name_Of (Current_Item);
886 if Pkg /= No_Package then
887 The_New_Package.Next :=
888 Packages.Table (Pkg).Decl.Packages;
889 Packages.Table (Pkg).Decl.Packages := New_Pkg;
890 else
891 The_New_Package.Next :=
892 Projects.Table (Project).Decl.Packages;
893 Projects.Table (Project).Decl.Packages := New_Pkg;
894 end if;
896 Packages.Table (New_Pkg) := The_New_Package;
898 if Project_Of_Renamed_Package /= Empty_Node then
900 -- Renamed package
902 declare
903 Project_Name : constant Name_Id :=
904 Name_Of
905 (Project_Of_Renamed_Package);
907 Renamed_Project : constant Project_Id :=
908 Imported_Or_Modified_Project_From
909 (Project, Project_Name);
911 Renamed_Package : constant Package_Id :=
912 Package_From
913 (Renamed_Project,
914 Name_Of (Current_Item));
916 begin
917 Packages.Table (New_Pkg).Decl :=
918 Packages.Table (Renamed_Package).Decl;
919 end;
921 else
922 -- Set the default values of the attributes
924 Add_Attributes
925 (Packages.Table (New_Pkg).Decl,
926 Package_Attributes.Table
927 (Package_Id_Of (Current_Item)).First_Attribute);
929 Process_Declarative_Items
930 (Project => Project,
931 From_Project_Node => From_Project_Node,
932 Pkg => New_Pkg,
933 Item => First_Declarative_Item_Of
934 (Current_Item));
935 end if;
937 end;
939 when N_String_Type_Declaration =>
941 -- There is nothing to process
943 null;
945 when N_Attribute_Declaration |
946 N_Typed_Variable_Declaration |
947 N_Variable_Declaration =>
949 pragma Assert (Expression_Of (Current_Item) /= Empty_Node,
950 "no expression for an object declaration");
952 declare
953 New_Value : constant Variable_Value :=
954 Expression
955 (Project => Project,
956 From_Project_Node => From_Project_Node,
957 Pkg => Pkg,
958 First_Term =>
959 Tree.First_Term (Expression_Of
960 (Current_Item)),
961 Kind =>
962 Expression_Kind_Of (Current_Item));
964 The_Variable : Variable_Id := No_Variable;
966 Current_Item_Name : constant Name_Id :=
967 Name_Of (Current_Item);
969 begin
970 if Kind_Of (Current_Item) = N_Typed_Variable_Declaration then
972 if String_Equal (New_Value.Value, Empty_String) then
973 Error_Msg_Name_1 := Name_Of (Current_Item);
975 if Error_Report = null then
976 Error_Msg
977 ("no value defined for %",
978 Location_Of (Current_Item));
980 else
981 Error_Report
982 ("no value defined for " &
983 Get_Name_String (Error_Msg_Name_1),
984 Project);
985 end if;
987 else
988 declare
989 Current_String : Project_Node_Id :=
990 First_Literal_String
991 (String_Type_Of
992 (Current_Item));
994 begin
995 while Current_String /= Empty_Node
996 and then not String_Equal
997 (String_Value_Of (Current_String),
998 New_Value.Value)
999 loop
1000 Current_String :=
1001 Next_Literal_String (Current_String);
1002 end loop;
1004 if Current_String = Empty_Node then
1005 String_To_Name_Buffer (New_Value.Value);
1006 Error_Msg_Name_1 := Name_Find;
1007 Error_Msg_Name_2 := Name_Of (Current_Item);
1009 if Error_Report = null then
1010 Error_Msg
1011 ("value { is illegal for typed string %",
1012 Location_Of (Current_Item));
1014 else
1015 Error_Report
1016 ("value """ &
1017 Get_Name_String (Error_Msg_Name_1) &
1018 """ is illegal for typed string """ &
1019 Get_Name_String (Error_Msg_Name_2) &
1020 """",
1021 Project);
1022 end if;
1023 end if;
1024 end;
1025 end if;
1026 end if;
1028 if Kind_Of (Current_Item) /= N_Attribute_Declaration
1029 or else
1030 Associative_Array_Index_Of (Current_Item) = No_String
1031 then
1032 -- Usual case
1034 -- Code below really needs more comments ???
1036 if Kind_Of (Current_Item) = N_Attribute_Declaration then
1037 if Pkg /= No_Package then
1038 The_Variable :=
1039 Packages.Table (Pkg).Decl.Attributes;
1041 else
1042 The_Variable :=
1043 Projects.Table (Project).Decl.Attributes;
1044 end if;
1046 else
1047 if Pkg /= No_Package then
1048 The_Variable :=
1049 Packages.Table (Pkg).Decl.Variables;
1051 else
1052 The_Variable :=
1053 Projects.Table (Project).Decl.Variables;
1054 end if;
1056 end if;
1058 while
1059 The_Variable /= No_Variable
1060 and then
1061 Variable_Elements.Table (The_Variable).Name /=
1062 Current_Item_Name
1063 loop
1064 The_Variable :=
1065 Variable_Elements.Table (The_Variable).Next;
1066 end loop;
1068 if The_Variable = No_Variable then
1069 pragma Assert
1070 (Kind_Of (Current_Item) /= N_Attribute_Declaration,
1071 "illegal attribute declaration");
1073 Variable_Elements.Increment_Last;
1074 The_Variable := Variable_Elements.Last;
1076 if Pkg /= No_Package then
1077 Variable_Elements.Table (The_Variable) :=
1078 (Next =>
1079 Packages.Table (Pkg).Decl.Variables,
1080 Name => Current_Item_Name,
1081 Value => New_Value);
1082 Packages.Table (Pkg).Decl.Variables := The_Variable;
1084 else
1085 Variable_Elements.Table (The_Variable) :=
1086 (Next =>
1087 Projects.Table (Project).Decl.Variables,
1088 Name => Current_Item_Name,
1089 Value => New_Value);
1090 Projects.Table (Project).Decl.Variables :=
1091 The_Variable;
1092 end if;
1094 else
1095 Variable_Elements.Table (The_Variable).Value :=
1096 New_Value;
1098 end if;
1100 else
1101 -- Associative array attribute
1103 String_To_Name_Buffer
1104 (Associative_Array_Index_Of (Current_Item));
1106 if Case_Insensitive (Current_Item) then
1107 GNAT.Case_Util.To_Lower (Name_Buffer (1 .. Name_Len));
1108 end if;
1110 declare
1111 The_Array : Array_Id;
1113 The_Array_Element : Array_Element_Id :=
1114 No_Array_Element;
1116 Index_Name : constant Name_Id := Name_Find;
1118 begin
1120 if Pkg /= No_Package then
1121 The_Array := Packages.Table (Pkg).Decl.Arrays;
1123 else
1124 The_Array := Projects.Table (Project).Decl.Arrays;
1125 end if;
1127 while
1128 The_Array /= No_Array
1129 and then Arrays.Table (The_Array).Name /=
1130 Current_Item_Name
1131 loop
1132 The_Array := Arrays.Table (The_Array).Next;
1133 end loop;
1135 if The_Array = No_Array then
1136 Arrays.Increment_Last;
1137 The_Array := Arrays.Last;
1139 if Pkg /= No_Package then
1140 Arrays.Table (The_Array) :=
1141 (Name => Current_Item_Name,
1142 Value => No_Array_Element,
1143 Next => Packages.Table (Pkg).Decl.Arrays);
1144 Packages.Table (Pkg).Decl.Arrays := The_Array;
1146 else
1147 Arrays.Table (The_Array) :=
1148 (Name => Current_Item_Name,
1149 Value => No_Array_Element,
1150 Next =>
1151 Projects.Table (Project).Decl.Arrays);
1152 Projects.Table (Project).Decl.Arrays :=
1153 The_Array;
1154 end if;
1156 else
1157 The_Array_Element := Arrays.Table (The_Array).Value;
1158 end if;
1160 while The_Array_Element /= No_Array_Element
1161 and then
1162 Array_Elements.Table (The_Array_Element).Index /=
1163 Index_Name
1164 loop
1165 The_Array_Element :=
1166 Array_Elements.Table (The_Array_Element).Next;
1167 end loop;
1169 if The_Array_Element = No_Array_Element then
1170 Array_Elements.Increment_Last;
1171 The_Array_Element := Array_Elements.Last;
1172 Array_Elements.Table (The_Array_Element) :=
1173 (Index => Index_Name,
1174 Value => New_Value,
1175 Next => Arrays.Table (The_Array).Value);
1176 Arrays.Table (The_Array).Value := The_Array_Element;
1178 else
1179 Array_Elements.Table (The_Array_Element).Value :=
1180 New_Value;
1181 end if;
1182 end;
1183 end if;
1184 end;
1186 when N_Case_Construction =>
1187 declare
1188 The_Project : Project_Id := Project;
1189 The_Package : Package_Id := Pkg;
1190 The_Variable : Variable_Value := Nil_Variable_Value;
1191 Case_Value : String_Id := No_String;
1192 Case_Item : Project_Node_Id := Empty_Node;
1193 Choice_String : Project_Node_Id := Empty_Node;
1194 Decl_Item : Project_Node_Id := Empty_Node;
1196 begin
1197 declare
1198 Variable_Node : constant Project_Node_Id :=
1199 Case_Variable_Reference_Of
1200 (Current_Item);
1202 Var_Id : Variable_Id := No_Variable;
1203 Name : Name_Id := No_Name;
1205 begin
1206 if Project_Node_Of (Variable_Node) /= Empty_Node then
1207 Name := Name_Of (Project_Node_Of (Variable_Node));
1208 The_Project :=
1209 Imported_Or_Modified_Project_From (Project, Name);
1210 end if;
1212 if Package_Node_Of (Variable_Node) /= Empty_Node then
1213 Name := Name_Of (Package_Node_Of (Variable_Node));
1214 The_Package := Package_From (The_Project, Name);
1215 end if;
1217 Name := Name_Of (Variable_Node);
1219 if The_Package /= No_Package then
1220 Var_Id := Packages.Table (The_Package).Decl.Variables;
1221 Name := Name_Of (Variable_Node);
1222 while Var_Id /= No_Variable
1223 and then
1224 Variable_Elements.Table (Var_Id).Name /= Name
1225 loop
1226 Var_Id := Variable_Elements.Table (Var_Id).Next;
1227 end loop;
1228 end if;
1230 if Var_Id = No_Variable
1231 and then Package_Node_Of (Variable_Node) = Empty_Node
1232 then
1233 Var_Id := Projects.Table (The_Project).Decl.Variables;
1234 while Var_Id /= No_Variable
1235 and then
1236 Variable_Elements.Table (Var_Id).Name /= Name
1237 loop
1238 Var_Id := Variable_Elements.Table (Var_Id).Next;
1239 end loop;
1240 end if;
1242 if Var_Id = No_Variable then
1244 -- Should never happen
1246 Write_Line ("variable """ &
1247 Get_Name_String (Name) &
1248 """ not found");
1249 raise Program_Error;
1250 end if;
1252 The_Variable := Variable_Elements.Table (Var_Id).Value;
1254 if The_Variable.Kind /= Single then
1256 -- Should never happen
1258 Write_Line ("variable""" &
1259 Get_Name_String (Name) &
1260 """ is not a single string variable");
1261 raise Program_Error;
1262 end if;
1264 Case_Value := The_Variable.Value;
1265 end;
1267 Case_Item := First_Case_Item_Of (Current_Item);
1268 Case_Item_Loop :
1269 while Case_Item /= Empty_Node loop
1270 Choice_String := First_Choice_Of (Case_Item);
1272 if Choice_String = Empty_Node then
1273 Decl_Item := First_Declarative_Item_Of (Case_Item);
1274 exit Case_Item_Loop;
1275 end if;
1277 Choice_Loop :
1278 while Choice_String /= Empty_Node loop
1279 if String_Equal (Case_Value,
1280 String_Value_Of (Choice_String))
1281 then
1282 Decl_Item :=
1283 First_Declarative_Item_Of (Case_Item);
1284 exit Case_Item_Loop;
1285 end if;
1287 Choice_String :=
1288 Next_Literal_String (Choice_String);
1289 end loop Choice_Loop;
1290 Case_Item := Next_Case_Item (Case_Item);
1291 end loop Case_Item_Loop;
1293 if Decl_Item /= Empty_Node then
1294 Process_Declarative_Items
1295 (Project => Project,
1296 From_Project_Node => From_Project_Node,
1297 Pkg => Pkg,
1298 Item => Decl_Item);
1299 end if;
1300 end;
1302 when others =>
1304 -- Should never happen
1306 Write_Line ("Illegal declarative item: " &
1307 Project_Node_Kind'Image (Kind_Of (Current_Item)));
1308 raise Program_Error;
1309 end case;
1310 end loop;
1311 end Process_Declarative_Items;
1313 ---------------------
1314 -- Recursive_Check --
1315 ---------------------
1317 procedure Recursive_Check (Project : Project_Id) is
1318 Data : Project_Data;
1319 Imported_Project_List : Project_List := Empty_Project_List;
1321 begin
1322 -- Do nothing if Project is No_Project, or Project has already
1323 -- been marked as checked.
1325 if Project /= No_Project
1326 and then not Projects.Table (Project).Checked
1327 then
1328 Data := Projects.Table (Project);
1330 -- Call itself for a possible modified project.
1331 -- (if there is no modified project, then nothing happens).
1333 Recursive_Check (Data.Modifies);
1335 -- Call itself for all imported projects
1337 Imported_Project_List := Data.Imported_Projects;
1338 while Imported_Project_List /= Empty_Project_List loop
1339 Recursive_Check
1340 (Project_Lists.Table (Imported_Project_List).Project);
1341 Imported_Project_List :=
1342 Project_Lists.Table (Imported_Project_List).Next;
1343 end loop;
1345 -- Mark project as checked
1347 Projects.Table (Project).Checked := True;
1349 if Opt.Verbose_Mode then
1350 Write_Str ("Checking project file """);
1351 Write_Str (Get_Name_String (Data.Name));
1352 Write_Line ("""");
1353 end if;
1355 Prj.Nmsc.Ada_Check (Project, Error_Report);
1356 end if;
1357 end Recursive_Check;
1359 -----------------------
1360 -- Recursive_Process --
1361 -----------------------
1363 procedure Recursive_Process
1364 (Project : out Project_Id;
1365 From_Project_Node : Project_Node_Id;
1366 Modified_By : Project_Id)
1368 With_Clause : Project_Node_Id;
1370 begin
1371 if From_Project_Node = Empty_Node then
1372 Project := No_Project;
1374 else
1375 declare
1376 Processed_Data : Project_Data := Empty_Project;
1377 Imported : Project_List := Empty_Project_List;
1378 Declaration_Node : Project_Node_Id := Empty_Node;
1379 Name : constant Name_Id :=
1380 Name_Of (From_Project_Node);
1382 begin
1383 Project := Processed_Projects.Get (Name);
1385 if Project /= No_Project then
1386 return;
1387 end if;
1389 Projects.Increment_Last;
1390 Project := Projects.Last;
1391 Processed_Projects.Set (Name, Project);
1393 Processed_Data.Name := Name;
1394 Processed_Data.Path_Name := Path_Name_Of (From_Project_Node);
1395 Processed_Data.Location := Location_Of (From_Project_Node);
1396 Processed_Data.Directory := Directory_Of (From_Project_Node);
1397 Processed_Data.Modified_By := Modified_By;
1398 Processed_Data.Naming := Standard_Naming_Data;
1400 Add_Attributes (Processed_Data.Decl, Attribute_First);
1401 With_Clause := First_With_Clause_Of (From_Project_Node);
1403 while With_Clause /= Empty_Node loop
1404 declare
1405 New_Project : Project_Id;
1406 New_Data : Project_Data;
1408 begin
1409 Recursive_Process
1410 (Project => New_Project,
1411 From_Project_Node => Project_Node_Of (With_Clause),
1412 Modified_By => No_Project);
1413 New_Data := Projects.Table (New_Project);
1415 -- If we were the first project to import it,
1416 -- set First_Referred_By to us.
1418 if New_Data.First_Referred_By = No_Project then
1419 New_Data.First_Referred_By := Project;
1420 Projects.Table (New_Project) := New_Data;
1421 end if;
1423 -- Add this project to our list of imported projects
1425 Project_Lists.Increment_Last;
1426 Project_Lists.Table (Project_Lists.Last) :=
1427 (Project => New_Project, Next => Empty_Project_List);
1429 -- Imported is the id of the last imported project.
1430 -- If it is nil, then this imported project is our first.
1432 if Imported = Empty_Project_List then
1433 Processed_Data.Imported_Projects := Project_Lists.Last;
1435 else
1436 Project_Lists.Table (Imported).Next := Project_Lists.Last;
1437 end if;
1439 Imported := Project_Lists.Last;
1441 With_Clause := Next_With_Clause_Of (With_Clause);
1442 end;
1443 end loop;
1445 Declaration_Node := Project_Declaration_Of (From_Project_Node);
1447 Recursive_Process
1448 (Project => Processed_Data.Modifies,
1449 From_Project_Node => Modified_Project_Of (Declaration_Node),
1450 Modified_By => Project);
1452 Projects.Table (Project) := Processed_Data;
1454 Process_Declarative_Items
1455 (Project => Project,
1456 From_Project_Node => From_Project_Node,
1457 Pkg => No_Package,
1458 Item => First_Declarative_Item_Of
1459 (Declaration_Node));
1461 end;
1462 end if;
1463 end Recursive_Process;
1465 end Prj.Proc;