1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2008, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Err_Vars; use Err_Vars;
28 with GNAT.Case_Util; use GNAT.Case_Util;
29 with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
32 with Prj.Attr; use Prj.Attr;
33 with Prj.Attr.PM; use Prj.Attr.PM;
34 with Prj.Err; use Prj.Err;
35 with Prj.Strt; use Prj.Strt;
36 with Prj.Tree; use Prj.Tree;
38 with Uintp; use Uintp;
42 package body Prj.Dect is
46 type Zone is (In_Project, In_Package, In_Case_Construction);
47 -- Used to indicate if we are parsing a package (In_Package),
48 -- a case construction (In_Case_Construction) or none of those two
51 procedure Parse_Attribute_Declaration
52 (In_Tree : Project_Node_Tree_Ref;
53 Attribute : out Project_Node_Id;
54 First_Attribute : Attribute_Node_Id;
55 Current_Project : Project_Node_Id;
56 Current_Package : Project_Node_Id;
57 Packages_To_Check : String_List_Access);
58 -- Parse an attribute declaration
60 procedure Parse_Case_Construction
61 (In_Tree : Project_Node_Tree_Ref;
62 Case_Construction : out Project_Node_Id;
63 First_Attribute : Attribute_Node_Id;
64 Current_Project : Project_Node_Id;
65 Current_Package : Project_Node_Id;
66 Packages_To_Check : String_List_Access);
67 -- Parse a case construction
69 procedure Parse_Declarative_Items
70 (In_Tree : Project_Node_Tree_Ref;
71 Declarations : out Project_Node_Id;
73 First_Attribute : Attribute_Node_Id;
74 Current_Project : Project_Node_Id;
75 Current_Package : Project_Node_Id;
76 Packages_To_Check : String_List_Access);
77 -- Parse declarative items. Depending on In_Zone, some declarative
78 -- items may be forbidden.
80 procedure Parse_Package_Declaration
81 (In_Tree : Project_Node_Tree_Ref;
82 Package_Declaration : out Project_Node_Id;
83 Current_Project : Project_Node_Id;
84 Packages_To_Check : String_List_Access);
85 -- Parse a package declaration
87 procedure Parse_String_Type_Declaration
88 (In_Tree : Project_Node_Tree_Ref;
89 String_Type : out Project_Node_Id;
90 Current_Project : Project_Node_Id);
91 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
93 procedure Parse_Variable_Declaration
94 (In_Tree : Project_Node_Tree_Ref;
95 Variable : out Project_Node_Id;
96 Current_Project : Project_Node_Id;
97 Current_Package : Project_Node_Id);
98 -- Parse a variable assignment
99 -- <variable_Name> := <expression>; OR
100 -- <variable_Name> : <string_type_Name> := <string_expression>;
107 (In_Tree : Project_Node_Tree_Ref;
108 Declarations : out Project_Node_Id;
109 Current_Project : Project_Node_Id;
110 Extends : Project_Node_Id;
111 Packages_To_Check : String_List_Access)
113 First_Declarative_Item : Project_Node_Id := Empty_Node;
118 (Of_Kind => N_Project_Declaration, In_Tree => In_Tree);
119 Set_Location_Of (Declarations, In_Tree, To => Token_Ptr);
120 Set_Extended_Project_Of (Declarations, In_Tree, To => Extends);
121 Set_Project_Declaration_Of (Current_Project, In_Tree, Declarations);
122 Parse_Declarative_Items
123 (Declarations => First_Declarative_Item,
125 In_Zone => In_Project,
126 First_Attribute => Prj.Attr.Attribute_First,
127 Current_Project => Current_Project,
128 Current_Package => Empty_Node,
129 Packages_To_Check => Packages_To_Check);
130 Set_First_Declarative_Item_Of
131 (Declarations, In_Tree, To => First_Declarative_Item);
134 ---------------------------------
135 -- Parse_Attribute_Declaration --
136 ---------------------------------
138 procedure Parse_Attribute_Declaration
139 (In_Tree : Project_Node_Tree_Ref;
140 Attribute : out Project_Node_Id;
141 First_Attribute : Attribute_Node_Id;
142 Current_Project : Project_Node_Id;
143 Current_Package : Project_Node_Id;
144 Packages_To_Check : String_List_Access)
146 Current_Attribute : Attribute_Node_Id := First_Attribute;
147 Full_Associative_Array : Boolean := False;
148 Attribute_Name : Name_Id := No_Name;
149 Optional_Index : Boolean := False;
150 Pkg_Id : Package_Node_Id := Empty_Package;
151 Ignore : Boolean := False;
156 (Of_Kind => N_Attribute_Declaration, In_Tree => In_Tree);
157 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
158 Set_Previous_Line_Node (Attribute);
164 -- Body may be an attribute name
166 if Token = Tok_Body then
167 Token := Tok_Identifier;
168 Token_Name := Snames.Name_Body;
171 Expect (Tok_Identifier, "identifier");
173 if Token = Tok_Identifier then
174 Attribute_Name := Token_Name;
175 Set_Name_Of (Attribute, In_Tree, To => Token_Name);
176 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
178 -- Find the attribute
181 Attribute_Node_Id_Of (Token_Name, First_Attribute);
183 -- If the attribute cannot be found, create the attribute if inside
184 -- an unknown package.
186 if Current_Attribute = Empty_Attribute then
187 if Present (Current_Package)
188 and then Expression_Kind_Of (Current_Package, In_Tree) = Ignored
190 Pkg_Id := Package_Id_Of (Current_Package, In_Tree);
191 Add_Attribute (Pkg_Id, Token_Name, Current_Attribute);
194 -- If not a valid attribute name, issue an error if inside
195 -- a package that need to be checked.
197 Ignore := Present (Current_Package) and then
198 Packages_To_Check /= All_Packages;
202 -- Check that we are not in a package to check
204 Get_Name_String (Name_Of (Current_Package, In_Tree));
206 for Index in Packages_To_Check'Range loop
207 if Name_Buffer (1 .. Name_Len) =
208 Packages_To_Check (Index).all
217 Error_Msg_Name_1 := Token_Name;
218 Error_Msg ("undefined attribute %%", Token_Ptr);
222 -- Set, if appropriate the index case insensitivity flag
225 if Is_Read_Only (Current_Attribute) then
226 Error_Msg_Name_1 := Token_Name;
228 ("read-only attribute %% cannot be given a value",
232 if Attribute_Kind_Of (Current_Attribute) in
233 Case_Insensitive_Associative_Array ..
234 Optional_Index_Case_Insensitive_Associative_Array
236 Set_Case_Insensitive (Attribute, In_Tree, To => True);
240 Scan (In_Tree); -- past the attribute name
243 -- Change obsolete names of attributes to the new names
245 if Present (Current_Package)
246 and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored
248 case Name_Of (Attribute, In_Tree) is
249 when Snames.Name_Specification =>
250 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec);
252 when Snames.Name_Specification_Suffix =>
253 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix);
255 when Snames.Name_Implementation =>
256 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body);
258 when Snames.Name_Implementation_Suffix =>
259 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix);
266 -- Associative array attributes
268 if Token = Tok_Left_Paren then
270 -- If the attribute is not an associative array attribute, report
271 -- an error. If this information is still unknown, set the kind
272 -- to Associative_Array.
274 if Current_Attribute /= Empty_Attribute
275 and then Attribute_Kind_Of (Current_Attribute) = Single
277 Error_Msg ("the attribute """ &
279 (Attribute_Name_Of (Current_Attribute)) &
280 """ cannot be an associative array",
281 Location_Of (Attribute, In_Tree));
283 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
284 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
287 Scan (In_Tree); -- past the left parenthesis
289 if Others_Allowed_For (Current_Attribute)
290 and then Token = Tok_Others
292 Set_Associative_Array_Index_Of
293 (Attribute, In_Tree, All_Other_Names);
294 Scan (In_Tree); -- past others
297 if Others_Allowed_For (Current_Attribute) then
298 Expect (Tok_String_Literal, "literal string or others");
300 Expect (Tok_String_Literal, "literal string");
303 if Token = Tok_String_Literal then
304 Get_Name_String (Token_Name);
306 if Case_Insensitive (Attribute, In_Tree) then
307 To_Lower (Name_Buffer (1 .. Name_Len));
310 Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find);
311 Scan (In_Tree); -- past the literal string index
313 if Token = Tok_At then
314 case Attribute_Kind_Of (Current_Attribute) is
315 when Optional_Index_Associative_Array |
316 Optional_Index_Case_Insensitive_Associative_Array =>
318 Expect (Tok_Integer_Literal, "integer literal");
320 if Token = Tok_Integer_Literal then
322 -- Set the source index value from given literal
325 Index : constant Int :=
326 UI_To_Int (Int_Literal_Value);
329 Error_Msg ("index cannot be zero", Token_Ptr);
332 (Attribute, In_Tree, To => Index);
340 Error_Msg ("index not allowed here", Token_Ptr);
343 if Token = Tok_Integer_Literal then
351 Expect (Tok_Right_Paren, "`)`");
353 if Token = Tok_Right_Paren then
354 Scan (In_Tree); -- past the right parenthesis
358 -- If it is an associative array attribute and there are no left
359 -- parenthesis, then this is a full associative array declaration.
360 -- Flag it as such for later processing of its value.
362 if Current_Attribute /= Empty_Attribute
364 Attribute_Kind_Of (Current_Attribute) /= Single
366 if Attribute_Kind_Of (Current_Attribute) = Unknown then
367 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
370 Full_Associative_Array := True;
375 -- Set the expression kind of the attribute
377 if Current_Attribute /= Empty_Attribute then
378 Set_Expression_Kind_Of
379 (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute));
380 Optional_Index := Optional_Index_Of (Current_Attribute);
383 Expect (Tok_Use, "USE");
385 if Token = Tok_Use then
388 if Full_Associative_Array then
390 -- Expect <project>'<same_attribute_name>, or
391 -- <project>.<same_package_name>'<same_attribute_name>
394 The_Project : Project_Node_Id := Empty_Node;
395 -- The node of the project where the associative array is
398 The_Package : Project_Node_Id := Empty_Node;
399 -- The node of the package where the associative array is
402 Project_Name : Name_Id := No_Name;
403 -- The name of the project where the associative array is
406 Location : Source_Ptr := No_Location;
407 -- The location of the project name
410 Expect (Tok_Identifier, "identifier");
412 if Token = Tok_Identifier then
413 Location := Token_Ptr;
415 -- Find the project node in the imported project or
416 -- in the project being extended.
418 The_Project := Imported_Or_Extended_Project_Of
419 (Current_Project, In_Tree, Token_Name);
421 if No (The_Project) then
422 Error_Msg ("unknown project", Location);
423 Scan (In_Tree); -- past the project name
426 Project_Name := Token_Name;
427 Scan (In_Tree); -- past the project name
429 -- If this is inside a package, a dot followed by the
430 -- name of the package must followed the project name.
432 if Present (Current_Package) then
433 Expect (Tok_Dot, "`.`");
435 if Token /= Tok_Dot then
436 The_Project := Empty_Node;
439 Scan (In_Tree); -- past the dot
440 Expect (Tok_Identifier, "identifier");
442 if Token /= Tok_Identifier then
443 The_Project := Empty_Node;
445 -- If it is not the same package name, issue error
448 Token_Name /= Name_Of (Current_Package, In_Tree)
450 The_Project := Empty_Node;
452 ("not the same package as " &
454 (Name_Of (Current_Package, In_Tree)),
459 First_Package_Of (The_Project, In_Tree);
461 -- Look for the package node
463 while Present (The_Package)
465 Name_Of (The_Package, In_Tree) /= Token_Name
468 Next_Package_In_Project
469 (The_Package, In_Tree);
472 -- If the package cannot be found in the
473 -- project, issue an error.
475 if No (The_Package) then
476 The_Project := Empty_Node;
477 Error_Msg_Name_2 := Project_Name;
478 Error_Msg_Name_1 := Token_Name;
480 ("package % not declared in project %",
484 Scan (In_Tree); -- past the package name
491 if Present (The_Project) then
493 -- Looking for '<same attribute name>
495 Expect (Tok_Apostrophe, "`''`");
497 if Token /= Tok_Apostrophe then
498 The_Project := Empty_Node;
501 Scan (In_Tree); -- past the apostrophe
502 Expect (Tok_Identifier, "identifier");
504 if Token /= Tok_Identifier then
505 The_Project := Empty_Node;
508 -- If it is not the same attribute name, issue error
510 if Token_Name /= Attribute_Name then
511 The_Project := Empty_Node;
512 Error_Msg_Name_1 := Attribute_Name;
513 Error_Msg ("invalid name, should be %", Token_Ptr);
516 Scan (In_Tree); -- past the attribute name
521 if No (The_Project) then
523 -- If there were any problem, set the attribute id to null,
524 -- so that the node will not be recorded.
526 Current_Attribute := Empty_Attribute;
529 -- Set the appropriate field in the node.
530 -- Note that the index and the expression are nil. This
531 -- characterizes full associative array attribute
534 Set_Associative_Project_Of (Attribute, In_Tree, The_Project);
535 Set_Associative_Package_Of (Attribute, In_Tree, The_Package);
539 -- Other attribute declarations (not full associative array)
543 Expression_Location : constant Source_Ptr := Token_Ptr;
544 -- The location of the first token of the expression
546 Expression : Project_Node_Id := Empty_Node;
547 -- The expression, value for the attribute declaration
550 -- Get the expression value and set it in the attribute node
554 Expression => Expression,
555 Current_Project => Current_Project,
556 Current_Package => Current_Package,
557 Optional_Index => Optional_Index);
558 Set_Expression_Of (Attribute, In_Tree, To => Expression);
560 -- If the expression is legal, but not of the right kind
561 -- for the attribute, issue an error.
563 if Current_Attribute /= Empty_Attribute
564 and then Present (Expression)
565 and then Variable_Kind_Of (Current_Attribute) /=
566 Expression_Kind_Of (Expression, In_Tree)
568 if Variable_Kind_Of (Current_Attribute) = Undefined then
571 To => Expression_Kind_Of (Expression, In_Tree));
575 ("wrong expression kind for attribute """ &
577 (Attribute_Name_Of (Current_Attribute)) &
579 Expression_Location);
586 -- If the attribute was not recognized, return an empty node.
587 -- It may be that it is not in a package to check, and the node will
588 -- not be added to the tree.
590 if Current_Attribute = Empty_Attribute then
591 Attribute := Empty_Node;
594 Set_End_Of_Line (Attribute);
595 Set_Previous_Line_Node (Attribute);
596 end Parse_Attribute_Declaration;
598 -----------------------------
599 -- Parse_Case_Construction --
600 -----------------------------
602 procedure Parse_Case_Construction
603 (In_Tree : Project_Node_Tree_Ref;
604 Case_Construction : out Project_Node_Id;
605 First_Attribute : Attribute_Node_Id;
606 Current_Project : Project_Node_Id;
607 Current_Package : Project_Node_Id;
608 Packages_To_Check : String_List_Access)
610 Current_Item : Project_Node_Id := Empty_Node;
611 Next_Item : Project_Node_Id := Empty_Node;
612 First_Case_Item : Boolean := True;
614 Variable_Location : Source_Ptr := No_Location;
616 String_Type : Project_Node_Id := Empty_Node;
618 Case_Variable : Project_Node_Id := Empty_Node;
620 First_Declarative_Item : Project_Node_Id := Empty_Node;
622 First_Choice : Project_Node_Id := Empty_Node;
624 When_Others : Boolean := False;
625 -- Set to True when there is a "when others =>" clause
630 (Of_Kind => N_Case_Construction, In_Tree => In_Tree);
631 Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr);
637 -- Get the switch variable
639 Expect (Tok_Identifier, "identifier");
641 if Token = Tok_Identifier then
642 Variable_Location := Token_Ptr;
643 Parse_Variable_Reference
645 Variable => Case_Variable,
646 Current_Project => Current_Project,
647 Current_Package => Current_Package);
648 Set_Case_Variable_Reference_Of
649 (Case_Construction, In_Tree, To => Case_Variable);
652 if Token /= Tok_Is then
657 if Present (Case_Variable) then
658 String_Type := String_Type_Of (Case_Variable, In_Tree);
660 if No (String_Type) then
661 Error_Msg ("variable """ &
662 Get_Name_String (Name_Of (Case_Variable, In_Tree)) &
668 Expect (Tok_Is, "IS");
670 if Token = Tok_Is then
671 Set_End_Of_Line (Case_Construction);
672 Set_Previous_Line_Node (Case_Construction);
673 Set_Next_End_Node (Case_Construction);
680 Start_New_Case_Construction (In_Tree, String_Type);
684 while Token = Tok_When loop
686 if First_Case_Item then
689 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
690 Set_First_Case_Item_Of
691 (Case_Construction, In_Tree, To => Current_Item);
692 First_Case_Item := False;
697 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
698 Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item);
699 Current_Item := Next_Item;
702 Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr);
708 if Token = Tok_Others then
711 -- Scan past "others"
715 Expect (Tok_Arrow, "`=>`");
716 Set_End_Of_Line (Current_Item);
717 Set_Previous_Line_Node (Current_Item);
719 -- Empty_Node in Field1 of a Case_Item indicates
720 -- the "when others =>" branch.
722 Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node);
724 Parse_Declarative_Items
726 Declarations => First_Declarative_Item,
727 In_Zone => In_Case_Construction,
728 First_Attribute => First_Attribute,
729 Current_Project => Current_Project,
730 Current_Package => Current_Package,
731 Packages_To_Check => Packages_To_Check);
733 -- "when others =>" must be the last branch, so save the
734 -- Case_Item and exit
736 Set_First_Declarative_Item_Of
737 (Current_Item, In_Tree, To => First_Declarative_Item);
743 First_Choice => First_Choice);
744 Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice);
746 Expect (Tok_Arrow, "`=>`");
747 Set_End_Of_Line (Current_Item);
748 Set_Previous_Line_Node (Current_Item);
750 Parse_Declarative_Items
752 Declarations => First_Declarative_Item,
753 In_Zone => In_Case_Construction,
754 First_Attribute => First_Attribute,
755 Current_Project => Current_Project,
756 Current_Package => Current_Package,
757 Packages_To_Check => Packages_To_Check);
759 Set_First_Declarative_Item_Of
760 (Current_Item, In_Tree, To => First_Declarative_Item);
765 End_Case_Construction
766 (Check_All_Labels => not When_Others and not Quiet_Output,
767 Case_Location => Location_Of (Case_Construction, In_Tree));
769 Expect (Tok_End, "`END CASE`");
770 Remove_Next_End_Node;
772 if Token = Tok_End then
778 Expect (Tok_Case, "CASE");
786 Expect (Tok_Semicolon, "`;`");
787 Set_Previous_End_Node (Case_Construction);
789 end Parse_Case_Construction;
791 -----------------------------
792 -- Parse_Declarative_Items --
793 -----------------------------
795 procedure Parse_Declarative_Items
796 (In_Tree : Project_Node_Tree_Ref;
797 Declarations : out Project_Node_Id;
799 First_Attribute : Attribute_Node_Id;
800 Current_Project : Project_Node_Id;
801 Current_Package : Project_Node_Id;
802 Packages_To_Check : String_List_Access)
804 Current_Declarative_Item : Project_Node_Id := Empty_Node;
805 Next_Declarative_Item : Project_Node_Id := Empty_Node;
806 Current_Declaration : Project_Node_Id := Empty_Node;
807 Item_Location : Source_Ptr := No_Location;
810 Declarations := Empty_Node;
813 -- We are always positioned at the token that precedes the first
814 -- token of the declarative element. Scan past it.
818 Item_Location := Token_Ptr;
821 when Tok_Identifier =>
823 if In_Zone = In_Case_Construction then
825 -- Check if the variable has already been declared
828 The_Variable : Project_Node_Id := Empty_Node;
831 if Present (Current_Package) then
833 First_Variable_Of (Current_Package, In_Tree);
834 elsif Present (Current_Project) then
836 First_Variable_Of (Current_Project, In_Tree);
839 while Present (The_Variable)
840 and then Name_Of (The_Variable, In_Tree) /=
843 The_Variable := Next_Variable (The_Variable, In_Tree);
846 -- It is an error to declare a variable in a case
847 -- construction for the first time.
849 if No (The_Variable) then
851 ("a variable cannot be declared " &
852 "for the first time here",
858 Parse_Variable_Declaration
861 Current_Project => Current_Project,
862 Current_Package => Current_Package);
864 Set_End_Of_Line (Current_Declaration);
865 Set_Previous_Line_Node (Current_Declaration);
869 Parse_Attribute_Declaration
871 Attribute => Current_Declaration,
872 First_Attribute => First_Attribute,
873 Current_Project => Current_Project,
874 Current_Package => Current_Package,
875 Packages_To_Check => Packages_To_Check);
877 Set_End_Of_Line (Current_Declaration);
878 Set_Previous_Line_Node (Current_Declaration);
882 Scan (In_Tree); -- past "null"
886 -- Package declaration
888 if In_Zone /= In_Project then
889 Error_Msg ("a package cannot be declared here", Token_Ptr);
892 Parse_Package_Declaration
894 Package_Declaration => Current_Declaration,
895 Current_Project => Current_Project,
896 Packages_To_Check => Packages_To_Check);
898 Set_Previous_End_Node (Current_Declaration);
902 -- Type String Declaration
904 if In_Zone /= In_Project then
905 Error_Msg ("a string type cannot be declared here",
909 Parse_String_Type_Declaration
911 String_Type => Current_Declaration,
912 Current_Project => Current_Project);
914 Set_End_Of_Line (Current_Declaration);
915 Set_Previous_Line_Node (Current_Declaration);
921 Parse_Case_Construction
923 Case_Construction => Current_Declaration,
924 First_Attribute => First_Attribute,
925 Current_Project => Current_Project,
926 Current_Package => Current_Package,
927 Packages_To_Check => Packages_To_Check);
929 Set_Previous_End_Node (Current_Declaration);
934 -- We are leaving Parse_Declarative_Items positioned
935 -- at the first token after the list of declarative items.
936 -- It could be "end" (for a project, a package declaration or
937 -- a case construction) or "when" (for a case construction)
941 Expect (Tok_Semicolon, "`;` after declarative items");
943 -- Insert an N_Declarative_Item in the tree, but only if
944 -- Current_Declaration is not an empty node.
946 if Present (Current_Declaration) then
947 if No (Current_Declarative_Item) then
948 Current_Declarative_Item :=
950 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
951 Declarations := Current_Declarative_Item;
954 Next_Declarative_Item :=
956 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
957 Set_Next_Declarative_Item
958 (Current_Declarative_Item, In_Tree,
959 To => Next_Declarative_Item);
960 Current_Declarative_Item := Next_Declarative_Item;
963 Set_Current_Item_Node
964 (Current_Declarative_Item, In_Tree,
965 To => Current_Declaration);
967 (Current_Declarative_Item, In_Tree, To => Item_Location);
970 end Parse_Declarative_Items;
972 -------------------------------
973 -- Parse_Package_Declaration --
974 -------------------------------
976 procedure Parse_Package_Declaration
977 (In_Tree : Project_Node_Tree_Ref;
978 Package_Declaration : out Project_Node_Id;
979 Current_Project : Project_Node_Id;
980 Packages_To_Check : String_List_Access)
982 First_Attribute : Attribute_Node_Id := Empty_Attribute;
983 Current_Package : Package_Node_Id := Empty_Package;
984 First_Declarative_Item : Project_Node_Id := Empty_Node;
986 Package_Location : constant Source_Ptr := Token_Ptr;
989 Package_Declaration :=
991 (Of_Kind => N_Package_Declaration, In_Tree => In_Tree);
992 Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location);
994 -- Scan past "package"
997 Expect (Tok_Identifier, "identifier");
999 if Token = Tok_Identifier then
1000 Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name);
1002 Current_Package := Package_Node_Id_Of (Token_Name);
1004 if Current_Package = Empty_Package then
1005 if not Quiet_Output then
1007 List : constant Strings.String_List := Package_Name_List;
1009 Name : constant String := Get_Name_String (Token_Name);
1012 -- Check for possible misspelling of a known package name
1016 if Index >= List'Last then
1023 GNAT.Spelling_Checker.Is_Bad_Spelling_Of
1024 (Name, List (Index).all);
1027 -- Issue warning(s) in verbose mode or when a possible
1028 -- misspelling has been found.
1030 if Verbose_Mode or else Index /= 0 then
1033 (Name_Of (Package_Declaration, In_Tree)) &
1034 """ is not a known package name",
1039 Error_Msg ("\?possible misspelling of """ &
1040 List (Index).all & """",
1046 -- Set the package declaration to "ignored" so that it is not
1047 -- processed by Prj.Proc.Process.
1049 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1051 -- Add the unknown package in the list of packages
1053 Add_Unknown_Package (Token_Name, Current_Package);
1055 elsif Current_Package = Unknown_Package then
1057 -- Set the package declaration to "ignored" so that it is not
1058 -- processed by Prj.Proc.Process.
1060 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1063 First_Attribute := First_Attribute_Of (Current_Package);
1067 (Package_Declaration, In_Tree, To => Current_Package);
1070 Current : Project_Node_Id :=
1071 First_Package_Of (Current_Project, In_Tree);
1074 while Present (Current)
1075 and then Name_Of (Current, In_Tree) /= Token_Name
1077 Current := Next_Package_In_Project (Current, In_Tree);
1080 if Present (Current) then
1083 Get_Name_String (Name_Of (Package_Declaration, In_Tree)) &
1084 """ is declared twice in the same project",
1088 -- Add the package to the project list
1090 Set_Next_Package_In_Project
1091 (Package_Declaration, In_Tree,
1092 To => First_Package_Of (Current_Project, In_Tree));
1093 Set_First_Package_Of
1094 (Current_Project, In_Tree, To => Package_Declaration);
1098 -- Scan past the package name
1103 if Token = Tok_Renames then
1104 if In_Configuration then
1106 ("no package renames in configuration projects", Token_Ptr);
1109 -- Scan past "renames"
1113 Expect (Tok_Identifier, "identifier");
1115 if Token = Tok_Identifier then
1117 Project_Name : constant Name_Id := Token_Name;
1119 Clause : Project_Node_Id :=
1120 First_With_Clause_Of (Current_Project, In_Tree);
1121 The_Project : Project_Node_Id := Empty_Node;
1122 Extended : constant Project_Node_Id :=
1124 (Project_Declaration_Of
1125 (Current_Project, In_Tree),
1128 while Present (Clause) loop
1129 -- Only non limited imported projects may be used in a
1130 -- renames declaration.
1133 Non_Limited_Project_Node_Of (Clause, In_Tree);
1134 exit when Present (The_Project)
1135 and then Name_Of (The_Project, In_Tree) = Project_Name;
1136 Clause := Next_With_Clause_Of (Clause, In_Tree);
1140 -- As we have not found the project in the imports, we check
1141 -- if it's the name of an eventual extended project.
1143 if Present (Extended)
1144 and then Name_Of (Extended, In_Tree) = Project_Name
1146 Set_Project_Of_Renamed_Package_Of
1147 (Package_Declaration, In_Tree, To => Extended);
1149 Error_Msg_Name_1 := Project_Name;
1151 ("% is not an imported or extended project", Token_Ptr);
1154 Set_Project_Of_Renamed_Package_Of
1155 (Package_Declaration, In_Tree, To => The_Project);
1160 Expect (Tok_Dot, "`.`");
1162 if Token = Tok_Dot then
1164 Expect (Tok_Identifier, "identifier");
1166 if Token = Tok_Identifier then
1167 if Name_Of (Package_Declaration, In_Tree) /= Token_Name then
1168 Error_Msg ("not the same package name", Token_Ptr);
1170 Present (Project_Of_Renamed_Package_Of
1171 (Package_Declaration, In_Tree))
1174 Current : Project_Node_Id :=
1176 (Project_Of_Renamed_Package_Of
1177 (Package_Declaration, In_Tree),
1181 while Present (Current)
1182 and then Name_Of (Current, In_Tree) /= Token_Name
1185 Next_Package_In_Project (Current, In_Tree);
1188 if No (Current) then
1191 Get_Name_String (Token_Name) &
1192 """ is not a package declared by the project",
1203 Expect (Tok_Semicolon, "`;`");
1204 Set_End_Of_Line (Package_Declaration);
1205 Set_Previous_Line_Node (Package_Declaration);
1207 elsif Token = Tok_Is then
1208 Set_End_Of_Line (Package_Declaration);
1209 Set_Previous_Line_Node (Package_Declaration);
1210 Set_Next_End_Node (Package_Declaration);
1212 Parse_Declarative_Items
1213 (In_Tree => In_Tree,
1214 Declarations => First_Declarative_Item,
1215 In_Zone => In_Package,
1216 First_Attribute => First_Attribute,
1217 Current_Project => Current_Project,
1218 Current_Package => Package_Declaration,
1219 Packages_To_Check => Packages_To_Check);
1221 Set_First_Declarative_Item_Of
1222 (Package_Declaration, In_Tree, To => First_Declarative_Item);
1224 Expect (Tok_End, "END");
1226 if Token = Tok_End then
1233 -- We should have the name of the package after "end"
1235 Expect (Tok_Identifier, "identifier");
1237 if Token = Tok_Identifier
1238 and then Name_Of (Package_Declaration, In_Tree) /= No_Name
1239 and then Token_Name /= Name_Of (Package_Declaration, In_Tree)
1241 Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree);
1242 Error_Msg ("expected %%", Token_Ptr);
1245 if Token /= Tok_Semicolon then
1247 -- Scan past the package name
1252 Expect (Tok_Semicolon, "`;`");
1253 Remove_Next_End_Node;
1256 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1259 end Parse_Package_Declaration;
1261 -----------------------------------
1262 -- Parse_String_Type_Declaration --
1263 -----------------------------------
1265 procedure Parse_String_Type_Declaration
1266 (In_Tree : Project_Node_Tree_Ref;
1267 String_Type : out Project_Node_Id;
1268 Current_Project : Project_Node_Id)
1270 Current : Project_Node_Id := Empty_Node;
1271 First_String : Project_Node_Id := Empty_Node;
1275 Default_Project_Node
1276 (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree);
1278 Set_Location_Of (String_Type, In_Tree, To => Token_Ptr);
1284 Expect (Tok_Identifier, "identifier");
1286 if Token = Tok_Identifier then
1287 Set_Name_Of (String_Type, In_Tree, To => Token_Name);
1289 Current := First_String_Type_Of (Current_Project, In_Tree);
1290 while Present (Current)
1292 Name_Of (Current, In_Tree) /= Token_Name
1294 Current := Next_String_Type (Current, In_Tree);
1297 if Present (Current) then
1298 Error_Msg ("duplicate string type name """ &
1299 Get_Name_String (Token_Name) &
1303 Current := First_Variable_Of (Current_Project, In_Tree);
1304 while Present (Current)
1305 and then Name_Of (Current, In_Tree) /= Token_Name
1307 Current := Next_Variable (Current, In_Tree);
1310 if Present (Current) then
1312 Get_Name_String (Token_Name) &
1313 """ is already a variable name", Token_Ptr);
1315 Set_Next_String_Type
1316 (String_Type, In_Tree,
1317 To => First_String_Type_Of (Current_Project, In_Tree));
1318 Set_First_String_Type_Of
1319 (Current_Project, In_Tree, To => String_Type);
1323 -- Scan past the name
1328 Expect (Tok_Is, "IS");
1330 if Token = Tok_Is then
1334 Expect (Tok_Left_Paren, "`(`");
1336 if Token = Tok_Left_Paren then
1340 Parse_String_Type_List
1341 (In_Tree => In_Tree, First_String => First_String);
1342 Set_First_Literal_String (String_Type, In_Tree, To => First_String);
1344 Expect (Tok_Right_Paren, "`)`");
1346 if Token = Tok_Right_Paren then
1350 end Parse_String_Type_Declaration;
1352 --------------------------------
1353 -- Parse_Variable_Declaration --
1354 --------------------------------
1356 procedure Parse_Variable_Declaration
1357 (In_Tree : Project_Node_Tree_Ref;
1358 Variable : out Project_Node_Id;
1359 Current_Project : Project_Node_Id;
1360 Current_Package : Project_Node_Id)
1362 Expression_Location : Source_Ptr;
1363 String_Type_Name : Name_Id := No_Name;
1364 Project_String_Type_Name : Name_Id := No_Name;
1365 Type_Location : Source_Ptr := No_Location;
1366 Project_Location : Source_Ptr := No_Location;
1367 Expression : Project_Node_Id := Empty_Node;
1368 Variable_Name : constant Name_Id := Token_Name;
1369 OK : Boolean := True;
1373 Default_Project_Node
1374 (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree);
1375 Set_Name_Of (Variable, In_Tree, To => Variable_Name);
1376 Set_Location_Of (Variable, In_Tree, To => Token_Ptr);
1378 -- Scan past the variable name
1382 if Token = Tok_Colon then
1384 -- Typed string variable declaration
1387 Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration);
1388 Expect (Tok_Identifier, "identifier");
1390 OK := Token = Tok_Identifier;
1393 String_Type_Name := Token_Name;
1394 Type_Location := Token_Ptr;
1397 if Token = Tok_Dot then
1398 Project_String_Type_Name := String_Type_Name;
1399 Project_Location := Type_Location;
1401 -- Scan past the dot
1404 Expect (Tok_Identifier, "identifier");
1406 if Token = Tok_Identifier then
1407 String_Type_Name := Token_Name;
1408 Type_Location := Token_Ptr;
1417 Proj : Project_Node_Id := Current_Project;
1418 Current : Project_Node_Id := Empty_Node;
1421 if Project_String_Type_Name /= No_Name then
1423 The_Project_Name_And_Node : constant
1424 Tree_Private_Part.Project_Name_And_Node :=
1425 Tree_Private_Part.Projects_Htable.Get
1426 (In_Tree.Projects_HT, Project_String_Type_Name);
1428 use Tree_Private_Part;
1431 if The_Project_Name_And_Node =
1432 Tree_Private_Part.No_Project_Name_And_Node
1434 Error_Msg ("unknown project """ &
1436 (Project_String_Type_Name) &
1439 Current := Empty_Node;
1442 First_String_Type_Of
1443 (The_Project_Name_And_Node.Node, In_Tree);
1447 Name_Of (Current, In_Tree) /= String_Type_Name
1449 Current := Next_String_Type (Current, In_Tree);
1455 -- Look for a string type with the correct name in this
1456 -- project or in any of its ancestors.
1460 First_String_Type_Of (Proj, In_Tree);
1464 Name_Of (Current, In_Tree) /= String_Type_Name
1466 Current := Next_String_Type (Current, In_Tree);
1469 exit when Present (Current);
1471 Proj := Parent_Project_Of (Proj, In_Tree);
1472 exit when No (Proj);
1476 if No (Current) then
1477 Error_Msg ("unknown string type """ &
1478 Get_Name_String (String_Type_Name) &
1485 (Variable, In_Tree, To => Current);
1492 Expect (Tok_Colon_Equal, "`:=`");
1494 OK := OK and (Token = Tok_Colon_Equal);
1496 if Token = Tok_Colon_Equal then
1500 -- Get the single string or string list value
1502 Expression_Location := Token_Ptr;
1505 (In_Tree => In_Tree,
1506 Expression => Expression,
1507 Current_Project => Current_Project,
1508 Current_Package => Current_Package,
1509 Optional_Index => False);
1510 Set_Expression_Of (Variable, In_Tree, To => Expression);
1512 if Present (Expression) then
1513 -- A typed string must have a single string value, not a list
1515 if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration
1516 and then Expression_Kind_Of (Expression, In_Tree) = List
1519 ("expression must be a single string", Expression_Location);
1522 Set_Expression_Kind_Of
1524 To => Expression_Kind_Of (Expression, In_Tree));
1529 The_Variable : Project_Node_Id := Empty_Node;
1532 if Present (Current_Package) then
1533 The_Variable := First_Variable_Of (Current_Package, In_Tree);
1534 elsif Present (Current_Project) then
1535 The_Variable := First_Variable_Of (Current_Project, In_Tree);
1538 while Present (The_Variable)
1539 and then Name_Of (The_Variable, In_Tree) /= Variable_Name
1541 The_Variable := Next_Variable (The_Variable, In_Tree);
1544 if No (The_Variable) then
1545 if Present (Current_Package) then
1548 To => First_Variable_Of (Current_Package, In_Tree));
1549 Set_First_Variable_Of
1550 (Current_Package, In_Tree, To => Variable);
1552 elsif Present (Current_Project) then
1555 To => First_Variable_Of (Current_Project, In_Tree));
1556 Set_First_Variable_Of
1557 (Current_Project, In_Tree, To => Variable);
1561 if Expression_Kind_Of (Variable, In_Tree) /= Undefined then
1562 if Expression_Kind_Of (The_Variable, In_Tree) =
1565 Set_Expression_Kind_Of
1566 (The_Variable, In_Tree,
1567 To => Expression_Kind_Of (Variable, In_Tree));
1570 if Expression_Kind_Of (The_Variable, In_Tree) /=
1571 Expression_Kind_Of (Variable, In_Tree)
1573 Error_Msg ("wrong expression kind for variable """ &
1575 (Name_Of (The_Variable, In_Tree)) &
1577 Expression_Location);
1584 end Parse_Variable_Declaration;