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 Current_Package /= Empty_Node
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 := Current_Package /= Empty_Node 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
227 ("read-only attribute cannot be given a value",
231 if Attribute_Kind_Of (Current_Attribute) in
232 Case_Insensitive_Associative_Array ..
233 Optional_Index_Case_Insensitive_Associative_Array
235 Set_Case_Insensitive (Attribute, In_Tree, To => True);
239 Scan (In_Tree); -- past the attribute name
242 -- Change obsolete names of attributes to the new names
244 if Current_Package /= Empty_Node
245 and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored
247 case Name_Of (Attribute, In_Tree) is
248 when Snames.Name_Specification =>
249 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec);
251 when Snames.Name_Specification_Suffix =>
252 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix);
254 when Snames.Name_Implementation =>
255 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body);
257 when Snames.Name_Implementation_Suffix =>
258 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix);
265 -- Associative array attributes
267 if Token = Tok_Left_Paren then
269 -- If the attribute is not an associative array attribute, report
270 -- an error. If this information is still unknown, set the kind
271 -- to Associative_Array.
273 if Current_Attribute /= Empty_Attribute
274 and then Attribute_Kind_Of (Current_Attribute) = Single
276 Error_Msg ("the attribute """ &
278 (Attribute_Name_Of (Current_Attribute)) &
279 """ cannot be an associative array",
280 Location_Of (Attribute, In_Tree));
282 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
283 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
286 Scan (In_Tree); -- past the left parenthesis
287 Expect (Tok_String_Literal, "literal string");
289 if Token = Tok_String_Literal then
290 Get_Name_String (Token_Name);
292 if Case_Insensitive (Attribute, In_Tree) then
293 To_Lower (Name_Buffer (1 .. Name_Len));
296 Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find);
297 Scan (In_Tree); -- past the literal string index
299 if Token = Tok_At then
300 case Attribute_Kind_Of (Current_Attribute) is
301 when Optional_Index_Associative_Array |
302 Optional_Index_Case_Insensitive_Associative_Array =>
304 Expect (Tok_Integer_Literal, "integer literal");
306 if Token = Tok_Integer_Literal then
308 -- Set the source index value from given literal
311 Index : constant Int :=
312 UI_To_Int (Int_Literal_Value);
315 Error_Msg ("index cannot be zero", Token_Ptr);
318 (Attribute, In_Tree, To => Index);
326 Error_Msg ("index not allowed here", Token_Ptr);
329 if Token = Tok_Integer_Literal then
336 Expect (Tok_Right_Paren, "`)`");
338 if Token = Tok_Right_Paren then
339 Scan (In_Tree); -- past the right parenthesis
343 -- If it is an associative array attribute and there are no left
344 -- parenthesis, then this is a full associative array declaration.
345 -- Flag it as such for later processing of its value.
347 if Current_Attribute /= Empty_Attribute
349 Attribute_Kind_Of (Current_Attribute) /= Single
351 if Attribute_Kind_Of (Current_Attribute) = Unknown then
352 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
355 Full_Associative_Array := True;
360 -- Set the expression kind of the attribute
362 if Current_Attribute /= Empty_Attribute then
363 Set_Expression_Kind_Of
364 (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute));
365 Optional_Index := Optional_Index_Of (Current_Attribute);
368 Expect (Tok_Use, "USE");
370 if Token = Tok_Use then
373 if Full_Associative_Array then
375 -- Expect <project>'<same_attribute_name>, or
376 -- <project>.<same_package_name>'<same_attribute_name>
379 The_Project : Project_Node_Id := Empty_Node;
380 -- The node of the project where the associative array is
383 The_Package : Project_Node_Id := Empty_Node;
384 -- The node of the package where the associative array is
387 Project_Name : Name_Id := No_Name;
388 -- The name of the project where the associative array is
391 Location : Source_Ptr := No_Location;
392 -- The location of the project name
395 Expect (Tok_Identifier, "identifier");
397 if Token = Tok_Identifier then
398 Location := Token_Ptr;
400 -- Find the project node in the imported project or
401 -- in the project being extended.
403 The_Project := Imported_Or_Extended_Project_Of
404 (Current_Project, In_Tree, Token_Name);
406 if The_Project = Empty_Node then
407 Error_Msg ("unknown project", Location);
408 Scan (In_Tree); -- past the project name
411 Project_Name := Token_Name;
412 Scan (In_Tree); -- past the project name
414 -- If this is inside a package, a dot followed by the
415 -- name of the package must followed the project name.
417 if Current_Package /= Empty_Node then
418 Expect (Tok_Dot, "`.`");
420 if Token /= Tok_Dot then
421 The_Project := Empty_Node;
424 Scan (In_Tree); -- past the dot
425 Expect (Tok_Identifier, "identifier");
427 if Token /= Tok_Identifier then
428 The_Project := Empty_Node;
430 -- If it is not the same package name, issue error
433 Token_Name /= Name_Of (Current_Package, In_Tree)
435 The_Project := Empty_Node;
437 ("not the same package as " &
439 (Name_Of (Current_Package, In_Tree)),
444 First_Package_Of (The_Project, In_Tree);
446 -- Look for the package node
448 while The_Package /= Empty_Node
450 Name_Of (The_Package, In_Tree) /= Token_Name
453 Next_Package_In_Project
454 (The_Package, In_Tree);
457 -- If the package cannot be found in the
458 -- project, issue an error.
460 if The_Package = Empty_Node then
461 The_Project := Empty_Node;
462 Error_Msg_Name_2 := Project_Name;
463 Error_Msg_Name_1 := Token_Name;
465 ("package % not declared in project %",
469 Scan (In_Tree); -- past the package name
476 if The_Project /= Empty_Node then
478 -- Looking for '<same attribute name>
480 Expect (Tok_Apostrophe, "`''`");
482 if Token /= Tok_Apostrophe then
483 The_Project := Empty_Node;
486 Scan (In_Tree); -- past the apostrophe
487 Expect (Tok_Identifier, "identifier");
489 if Token /= Tok_Identifier then
490 The_Project := Empty_Node;
493 -- If it is not the same attribute name, issue error
495 if Token_Name /= Attribute_Name then
496 The_Project := Empty_Node;
497 Error_Msg_Name_1 := Attribute_Name;
498 Error_Msg ("invalid name, should be %", Token_Ptr);
501 Scan (In_Tree); -- past the attribute name
506 if The_Project = Empty_Node then
508 -- If there were any problem, set the attribute id to null,
509 -- so that the node will not be recorded.
511 Current_Attribute := Empty_Attribute;
514 -- Set the appropriate field in the node.
515 -- Note that the index and the expression are nil. This
516 -- characterizes full associative array attribute
519 Set_Associative_Project_Of (Attribute, In_Tree, The_Project);
520 Set_Associative_Package_Of (Attribute, In_Tree, The_Package);
524 -- Other attribute declarations (not full associative array)
528 Expression_Location : constant Source_Ptr := Token_Ptr;
529 -- The location of the first token of the expression
531 Expression : Project_Node_Id := Empty_Node;
532 -- The expression, value for the attribute declaration
535 -- Get the expression value and set it in the attribute node
539 Expression => Expression,
540 Current_Project => Current_Project,
541 Current_Package => Current_Package,
542 Optional_Index => Optional_Index);
543 Set_Expression_Of (Attribute, In_Tree, To => Expression);
545 -- If the expression is legal, but not of the right kind
546 -- for the attribute, issue an error.
548 if Current_Attribute /= Empty_Attribute
549 and then Expression /= Empty_Node
550 and then Variable_Kind_Of (Current_Attribute) /=
551 Expression_Kind_Of (Expression, In_Tree)
553 if Variable_Kind_Of (Current_Attribute) = Undefined then
556 To => Expression_Kind_Of (Expression, In_Tree));
560 ("wrong expression kind for attribute """ &
562 (Attribute_Name_Of (Current_Attribute)) &
564 Expression_Location);
571 -- If the attribute was not recognized, return an empty node.
572 -- It may be that it is not in a package to check, and the node will
573 -- not be added to the tree.
575 if Current_Attribute = Empty_Attribute then
576 Attribute := Empty_Node;
579 Set_End_Of_Line (Attribute);
580 Set_Previous_Line_Node (Attribute);
581 end Parse_Attribute_Declaration;
583 -----------------------------
584 -- Parse_Case_Construction --
585 -----------------------------
587 procedure Parse_Case_Construction
588 (In_Tree : Project_Node_Tree_Ref;
589 Case_Construction : out Project_Node_Id;
590 First_Attribute : Attribute_Node_Id;
591 Current_Project : Project_Node_Id;
592 Current_Package : Project_Node_Id;
593 Packages_To_Check : String_List_Access)
595 Current_Item : Project_Node_Id := Empty_Node;
596 Next_Item : Project_Node_Id := Empty_Node;
597 First_Case_Item : Boolean := True;
599 Variable_Location : Source_Ptr := No_Location;
601 String_Type : Project_Node_Id := Empty_Node;
603 Case_Variable : Project_Node_Id := Empty_Node;
605 First_Declarative_Item : Project_Node_Id := Empty_Node;
607 First_Choice : Project_Node_Id := Empty_Node;
609 When_Others : Boolean := False;
610 -- Set to True when there is a "when others =>" clause
615 (Of_Kind => N_Case_Construction, In_Tree => In_Tree);
616 Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr);
622 -- Get the switch variable
624 Expect (Tok_Identifier, "identifier");
626 if Token = Tok_Identifier then
627 Variable_Location := Token_Ptr;
628 Parse_Variable_Reference
630 Variable => Case_Variable,
631 Current_Project => Current_Project,
632 Current_Package => Current_Package);
633 Set_Case_Variable_Reference_Of
634 (Case_Construction, In_Tree, To => Case_Variable);
637 if Token /= Tok_Is then
642 if Case_Variable /= Empty_Node then
643 String_Type := String_Type_Of (Case_Variable, In_Tree);
645 if String_Type = Empty_Node then
646 Error_Msg ("variable """ &
647 Get_Name_String (Name_Of (Case_Variable, In_Tree)) &
653 Expect (Tok_Is, "IS");
655 if Token = Tok_Is then
656 Set_End_Of_Line (Case_Construction);
657 Set_Previous_Line_Node (Case_Construction);
658 Set_Next_End_Node (Case_Construction);
665 Start_New_Case_Construction (In_Tree, String_Type);
669 while Token = Tok_When loop
671 if First_Case_Item then
674 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
675 Set_First_Case_Item_Of
676 (Case_Construction, In_Tree, To => Current_Item);
677 First_Case_Item := False;
682 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
683 Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item);
684 Current_Item := Next_Item;
687 Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr);
693 if Token = Tok_Others then
696 -- Scan past "others"
700 Expect (Tok_Arrow, "`=>`");
701 Set_End_Of_Line (Current_Item);
702 Set_Previous_Line_Node (Current_Item);
704 -- Empty_Node in Field1 of a Case_Item indicates
705 -- the "when others =>" branch.
707 Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node);
709 Parse_Declarative_Items
711 Declarations => First_Declarative_Item,
712 In_Zone => In_Case_Construction,
713 First_Attribute => First_Attribute,
714 Current_Project => Current_Project,
715 Current_Package => Current_Package,
716 Packages_To_Check => Packages_To_Check);
718 -- "when others =>" must be the last branch, so save the
719 -- Case_Item and exit
721 Set_First_Declarative_Item_Of
722 (Current_Item, In_Tree, To => First_Declarative_Item);
728 First_Choice => First_Choice);
729 Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice);
731 Expect (Tok_Arrow, "`=>`");
732 Set_End_Of_Line (Current_Item);
733 Set_Previous_Line_Node (Current_Item);
735 Parse_Declarative_Items
737 Declarations => First_Declarative_Item,
738 In_Zone => In_Case_Construction,
739 First_Attribute => First_Attribute,
740 Current_Project => Current_Project,
741 Current_Package => Current_Package,
742 Packages_To_Check => Packages_To_Check);
744 Set_First_Declarative_Item_Of
745 (Current_Item, In_Tree, To => First_Declarative_Item);
750 End_Case_Construction
751 (Check_All_Labels => not When_Others and not Quiet_Output,
752 Case_Location => Location_Of (Case_Construction, In_Tree));
754 Expect (Tok_End, "`END CASE`");
755 Remove_Next_End_Node;
757 if Token = Tok_End then
763 Expect (Tok_Case, "CASE");
771 Expect (Tok_Semicolon, "`;`");
772 Set_Previous_End_Node (Case_Construction);
774 end Parse_Case_Construction;
776 -----------------------------
777 -- Parse_Declarative_Items --
778 -----------------------------
780 procedure Parse_Declarative_Items
781 (In_Tree : Project_Node_Tree_Ref;
782 Declarations : out Project_Node_Id;
784 First_Attribute : Attribute_Node_Id;
785 Current_Project : Project_Node_Id;
786 Current_Package : Project_Node_Id;
787 Packages_To_Check : String_List_Access)
789 Current_Declarative_Item : Project_Node_Id := Empty_Node;
790 Next_Declarative_Item : Project_Node_Id := Empty_Node;
791 Current_Declaration : Project_Node_Id := Empty_Node;
792 Item_Location : Source_Ptr := No_Location;
795 Declarations := Empty_Node;
798 -- We are always positioned at the token that precedes the first
799 -- token of the declarative element. Scan past it.
803 Item_Location := Token_Ptr;
806 when Tok_Identifier =>
808 if In_Zone = In_Case_Construction then
810 -- Check if the variable has already been declared
813 The_Variable : Project_Node_Id := Empty_Node;
816 if Current_Package /= Empty_Node then
818 First_Variable_Of (Current_Package, In_Tree);
819 elsif Current_Project /= Empty_Node then
821 First_Variable_Of (Current_Project, In_Tree);
824 while The_Variable /= Empty_Node
825 and then Name_Of (The_Variable, In_Tree) /=
828 The_Variable := Next_Variable (The_Variable, In_Tree);
831 -- It is an error to declare a variable in a case
832 -- construction for the first time.
834 if The_Variable = Empty_Node then
836 ("a variable cannot be declared " &
837 "for the first time here",
843 Parse_Variable_Declaration
846 Current_Project => Current_Project,
847 Current_Package => Current_Package);
849 Set_End_Of_Line (Current_Declaration);
850 Set_Previous_Line_Node (Current_Declaration);
854 Parse_Attribute_Declaration
856 Attribute => Current_Declaration,
857 First_Attribute => First_Attribute,
858 Current_Project => Current_Project,
859 Current_Package => Current_Package,
860 Packages_To_Check => Packages_To_Check);
862 Set_End_Of_Line (Current_Declaration);
863 Set_Previous_Line_Node (Current_Declaration);
867 Scan (In_Tree); -- past "null"
871 -- Package declaration
873 if In_Zone /= In_Project then
874 Error_Msg ("a package cannot be declared here", Token_Ptr);
877 Parse_Package_Declaration
879 Package_Declaration => Current_Declaration,
880 Current_Project => Current_Project,
881 Packages_To_Check => Packages_To_Check);
883 Set_Previous_End_Node (Current_Declaration);
887 -- Type String Declaration
889 if In_Zone /= In_Project then
890 Error_Msg ("a string type cannot be declared here",
894 Parse_String_Type_Declaration
896 String_Type => Current_Declaration,
897 Current_Project => Current_Project);
899 Set_End_Of_Line (Current_Declaration);
900 Set_Previous_Line_Node (Current_Declaration);
906 Parse_Case_Construction
908 Case_Construction => Current_Declaration,
909 First_Attribute => First_Attribute,
910 Current_Project => Current_Project,
911 Current_Package => Current_Package,
912 Packages_To_Check => Packages_To_Check);
914 Set_Previous_End_Node (Current_Declaration);
919 -- We are leaving Parse_Declarative_Items positioned
920 -- at the first token after the list of declarative items.
921 -- It could be "end" (for a project, a package declaration or
922 -- a case construction) or "when" (for a case construction)
926 Expect (Tok_Semicolon, "`;` after declarative items");
928 -- Insert an N_Declarative_Item in the tree, but only if
929 -- Current_Declaration is not an empty node.
931 if Current_Declaration /= Empty_Node then
932 if Current_Declarative_Item = Empty_Node then
933 Current_Declarative_Item :=
935 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
936 Declarations := Current_Declarative_Item;
939 Next_Declarative_Item :=
941 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
942 Set_Next_Declarative_Item
943 (Current_Declarative_Item, In_Tree,
944 To => Next_Declarative_Item);
945 Current_Declarative_Item := Next_Declarative_Item;
948 Set_Current_Item_Node
949 (Current_Declarative_Item, In_Tree,
950 To => Current_Declaration);
952 (Current_Declarative_Item, In_Tree, To => Item_Location);
955 end Parse_Declarative_Items;
957 -------------------------------
958 -- Parse_Package_Declaration --
959 -------------------------------
961 procedure Parse_Package_Declaration
962 (In_Tree : Project_Node_Tree_Ref;
963 Package_Declaration : out Project_Node_Id;
964 Current_Project : Project_Node_Id;
965 Packages_To_Check : String_List_Access)
967 First_Attribute : Attribute_Node_Id := Empty_Attribute;
968 Current_Package : Package_Node_Id := Empty_Package;
969 First_Declarative_Item : Project_Node_Id := Empty_Node;
971 Package_Location : constant Source_Ptr := Token_Ptr;
974 Package_Declaration :=
976 (Of_Kind => N_Package_Declaration, In_Tree => In_Tree);
977 Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location);
979 -- Scan past "package"
982 Expect (Tok_Identifier, "identifier");
984 if Token = Tok_Identifier then
985 Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name);
987 Current_Package := Package_Node_Id_Of (Token_Name);
989 if Current_Package = Empty_Package then
990 if not Quiet_Output then
992 List : constant Strings.String_List := Package_Name_List;
994 Name : constant String := Get_Name_String (Token_Name);
997 -- Check for possible misspelling of a known package name
1001 if Index >= List'Last then
1008 GNAT.Spelling_Checker.Is_Bad_Spelling_Of
1009 (Name, List (Index).all);
1012 -- Issue warning(s) in verbose mode or when a possible
1013 -- misspelling has been found.
1015 if Verbose_Mode or else Index /= 0 then
1018 (Name_Of (Package_Declaration, In_Tree)) &
1019 """ is not a known package name",
1024 Error_Msg ("\?possible misspelling of """ &
1025 List (Index).all & """",
1031 -- Set the package declaration to "ignored" so that it is not
1032 -- processed by Prj.Proc.Process.
1034 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1036 -- Add the unknown package in the list of packages
1038 Add_Unknown_Package (Token_Name, Current_Package);
1040 elsif Current_Package = Unknown_Package then
1042 -- Set the package declaration to "ignored" so that it is not
1043 -- processed by Prj.Proc.Process.
1045 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1048 First_Attribute := First_Attribute_Of (Current_Package);
1052 (Package_Declaration, In_Tree, To => Current_Package);
1055 Current : Project_Node_Id :=
1056 First_Package_Of (Current_Project, In_Tree);
1059 while Current /= Empty_Node
1060 and then Name_Of (Current, In_Tree) /= Token_Name
1062 Current := Next_Package_In_Project (Current, In_Tree);
1065 if Current /= Empty_Node then
1068 Get_Name_String (Name_Of (Package_Declaration, In_Tree)) &
1069 """ is declared twice in the same project",
1073 -- Add the package to the project list
1075 Set_Next_Package_In_Project
1076 (Package_Declaration, In_Tree,
1077 To => First_Package_Of (Current_Project, In_Tree));
1078 Set_First_Package_Of
1079 (Current_Project, In_Tree, To => Package_Declaration);
1083 -- Scan past the package name
1088 if Token = Tok_Renames then
1089 if In_Configuration then
1091 ("no package renames in configuration projects", Token_Ptr);
1094 -- Scan past "renames"
1098 Expect (Tok_Identifier, "identifier");
1100 if Token = Tok_Identifier then
1102 Project_Name : constant Name_Id := Token_Name;
1104 Clause : Project_Node_Id :=
1105 First_With_Clause_Of (Current_Project, In_Tree);
1106 The_Project : Project_Node_Id := Empty_Node;
1107 Extended : constant Project_Node_Id :=
1109 (Project_Declaration_Of
1110 (Current_Project, In_Tree),
1113 while Clause /= Empty_Node loop
1114 -- Only non limited imported projects may be used in a
1115 -- renames declaration.
1118 Non_Limited_Project_Node_Of (Clause, In_Tree);
1119 exit when The_Project /= Empty_Node
1120 and then Name_Of (The_Project, In_Tree) = Project_Name;
1121 Clause := Next_With_Clause_Of (Clause, In_Tree);
1124 if Clause = Empty_Node then
1125 -- As we have not found the project in the imports, we check
1126 -- if it's the name of an eventual extended project.
1128 if Extended /= Empty_Node
1129 and then Name_Of (Extended, In_Tree) = Project_Name
1131 Set_Project_Of_Renamed_Package_Of
1132 (Package_Declaration, In_Tree, To => Extended);
1134 Error_Msg_Name_1 := Project_Name;
1136 ("% is not an imported or extended project", Token_Ptr);
1139 Set_Project_Of_Renamed_Package_Of
1140 (Package_Declaration, In_Tree, To => The_Project);
1145 Expect (Tok_Dot, "`.`");
1147 if Token = Tok_Dot then
1149 Expect (Tok_Identifier, "identifier");
1151 if Token = Tok_Identifier then
1152 if Name_Of (Package_Declaration, In_Tree) /= Token_Name then
1153 Error_Msg ("not the same package name", Token_Ptr);
1155 Project_Of_Renamed_Package_Of
1156 (Package_Declaration, In_Tree) /= Empty_Node
1159 Current : Project_Node_Id :=
1161 (Project_Of_Renamed_Package_Of
1162 (Package_Declaration, In_Tree),
1166 while Current /= Empty_Node
1167 and then Name_Of (Current, In_Tree) /= Token_Name
1170 Next_Package_In_Project (Current, In_Tree);
1173 if Current = Empty_Node then
1176 Get_Name_String (Token_Name) &
1177 """ is not a package declared by the project",
1188 Expect (Tok_Semicolon, "`;`");
1189 Set_End_Of_Line (Package_Declaration);
1190 Set_Previous_Line_Node (Package_Declaration);
1192 elsif Token = Tok_Is then
1193 Set_End_Of_Line (Package_Declaration);
1194 Set_Previous_Line_Node (Package_Declaration);
1195 Set_Next_End_Node (Package_Declaration);
1197 Parse_Declarative_Items
1198 (In_Tree => In_Tree,
1199 Declarations => First_Declarative_Item,
1200 In_Zone => In_Package,
1201 First_Attribute => First_Attribute,
1202 Current_Project => Current_Project,
1203 Current_Package => Package_Declaration,
1204 Packages_To_Check => Packages_To_Check);
1206 Set_First_Declarative_Item_Of
1207 (Package_Declaration, In_Tree, To => First_Declarative_Item);
1209 Expect (Tok_End, "END");
1211 if Token = Tok_End then
1218 -- We should have the name of the package after "end"
1220 Expect (Tok_Identifier, "identifier");
1222 if Token = Tok_Identifier
1223 and then Name_Of (Package_Declaration, In_Tree) /= No_Name
1224 and then Token_Name /= Name_Of (Package_Declaration, In_Tree)
1226 Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree);
1227 Error_Msg ("expected %%", Token_Ptr);
1230 if Token /= Tok_Semicolon then
1232 -- Scan past the package name
1237 Expect (Tok_Semicolon, "`;`");
1238 Remove_Next_End_Node;
1241 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1244 end Parse_Package_Declaration;
1246 -----------------------------------
1247 -- Parse_String_Type_Declaration --
1248 -----------------------------------
1250 procedure Parse_String_Type_Declaration
1251 (In_Tree : Project_Node_Tree_Ref;
1252 String_Type : out Project_Node_Id;
1253 Current_Project : Project_Node_Id)
1255 Current : Project_Node_Id := Empty_Node;
1256 First_String : Project_Node_Id := Empty_Node;
1260 Default_Project_Node
1261 (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree);
1263 Set_Location_Of (String_Type, In_Tree, To => Token_Ptr);
1269 Expect (Tok_Identifier, "identifier");
1271 if Token = Tok_Identifier then
1272 Set_Name_Of (String_Type, In_Tree, To => Token_Name);
1274 Current := First_String_Type_Of (Current_Project, In_Tree);
1275 while Current /= Empty_Node
1277 Name_Of (Current, In_Tree) /= Token_Name
1279 Current := Next_String_Type (Current, In_Tree);
1282 if Current /= Empty_Node then
1283 Error_Msg ("duplicate string type name """ &
1284 Get_Name_String (Token_Name) &
1288 Current := First_Variable_Of (Current_Project, In_Tree);
1289 while Current /= Empty_Node
1290 and then Name_Of (Current, In_Tree) /= Token_Name
1292 Current := Next_Variable (Current, In_Tree);
1295 if Current /= Empty_Node then
1297 Get_Name_String (Token_Name) &
1298 """ is already a variable name", Token_Ptr);
1300 Set_Next_String_Type
1301 (String_Type, In_Tree,
1302 To => First_String_Type_Of (Current_Project, In_Tree));
1303 Set_First_String_Type_Of
1304 (Current_Project, In_Tree, To => String_Type);
1308 -- Scan past the name
1313 Expect (Tok_Is, "IS");
1315 if Token = Tok_Is then
1319 Expect (Tok_Left_Paren, "`(`");
1321 if Token = Tok_Left_Paren then
1325 Parse_String_Type_List
1326 (In_Tree => In_Tree, First_String => First_String);
1327 Set_First_Literal_String (String_Type, In_Tree, To => First_String);
1329 Expect (Tok_Right_Paren, "`)`");
1331 if Token = Tok_Right_Paren then
1335 end Parse_String_Type_Declaration;
1337 --------------------------------
1338 -- Parse_Variable_Declaration --
1339 --------------------------------
1341 procedure Parse_Variable_Declaration
1342 (In_Tree : Project_Node_Tree_Ref;
1343 Variable : out Project_Node_Id;
1344 Current_Project : Project_Node_Id;
1345 Current_Package : Project_Node_Id)
1347 Expression_Location : Source_Ptr;
1348 String_Type_Name : Name_Id := No_Name;
1349 Project_String_Type_Name : Name_Id := No_Name;
1350 Type_Location : Source_Ptr := No_Location;
1351 Project_Location : Source_Ptr := No_Location;
1352 Expression : Project_Node_Id := Empty_Node;
1353 Variable_Name : constant Name_Id := Token_Name;
1354 OK : Boolean := True;
1358 Default_Project_Node
1359 (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree);
1360 Set_Name_Of (Variable, In_Tree, To => Variable_Name);
1361 Set_Location_Of (Variable, In_Tree, To => Token_Ptr);
1363 -- Scan past the variable name
1367 if Token = Tok_Colon then
1369 -- Typed string variable declaration
1372 Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration);
1373 Expect (Tok_Identifier, "identifier");
1375 OK := Token = Tok_Identifier;
1378 String_Type_Name := Token_Name;
1379 Type_Location := Token_Ptr;
1382 if Token = Tok_Dot then
1383 Project_String_Type_Name := String_Type_Name;
1384 Project_Location := Type_Location;
1386 -- Scan past the dot
1389 Expect (Tok_Identifier, "identifier");
1391 if Token = Tok_Identifier then
1392 String_Type_Name := Token_Name;
1393 Type_Location := Token_Ptr;
1402 Current : Project_Node_Id :=
1403 First_String_Type_Of (Current_Project, In_Tree);
1406 if Project_String_Type_Name /= No_Name then
1408 The_Project_Name_And_Node : constant
1409 Tree_Private_Part.Project_Name_And_Node :=
1410 Tree_Private_Part.Projects_Htable.Get
1411 (In_Tree.Projects_HT, Project_String_Type_Name);
1413 use Tree_Private_Part;
1416 if The_Project_Name_And_Node =
1417 Tree_Private_Part.No_Project_Name_And_Node
1419 Error_Msg ("unknown project """ &
1421 (Project_String_Type_Name) &
1424 Current := Empty_Node;
1427 First_String_Type_Of
1428 (The_Project_Name_And_Node.Node, In_Tree);
1433 while Current /= Empty_Node
1434 and then Name_Of (Current, In_Tree) /= String_Type_Name
1436 Current := Next_String_Type (Current, In_Tree);
1439 if Current = Empty_Node then
1440 Error_Msg ("unknown string type """ &
1441 Get_Name_String (String_Type_Name) &
1447 (Variable, In_Tree, To => Current);
1454 Expect (Tok_Colon_Equal, "`:=`");
1456 OK := OK and (Token = Tok_Colon_Equal);
1458 if Token = Tok_Colon_Equal then
1462 -- Get the single string or string list value
1464 Expression_Location := Token_Ptr;
1467 (In_Tree => In_Tree,
1468 Expression => Expression,
1469 Current_Project => Current_Project,
1470 Current_Package => Current_Package,
1471 Optional_Index => False);
1472 Set_Expression_Of (Variable, In_Tree, To => Expression);
1474 if Expression /= Empty_Node then
1475 -- A typed string must have a single string value, not a list
1477 if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration
1478 and then Expression_Kind_Of (Expression, In_Tree) = List
1481 ("expression must be a single string", Expression_Location);
1484 Set_Expression_Kind_Of
1486 To => Expression_Kind_Of (Expression, In_Tree));
1491 The_Variable : Project_Node_Id := Empty_Node;
1494 if Current_Package /= Empty_Node then
1495 The_Variable := First_Variable_Of (Current_Package, In_Tree);
1496 elsif Current_Project /= Empty_Node then
1497 The_Variable := First_Variable_Of (Current_Project, In_Tree);
1500 while The_Variable /= Empty_Node
1501 and then Name_Of (The_Variable, In_Tree) /= Variable_Name
1503 The_Variable := Next_Variable (The_Variable, In_Tree);
1506 if The_Variable = Empty_Node then
1507 if Current_Package /= Empty_Node then
1510 To => First_Variable_Of (Current_Package, In_Tree));
1511 Set_First_Variable_Of
1512 (Current_Package, In_Tree, To => Variable);
1514 elsif Current_Project /= Empty_Node then
1517 To => First_Variable_Of (Current_Project, In_Tree));
1518 Set_First_Variable_Of
1519 (Current_Project, In_Tree, To => Variable);
1523 if Expression_Kind_Of (Variable, In_Tree) /= Undefined then
1525 Expression_Kind_Of (The_Variable, In_Tree) = Undefined
1527 Set_Expression_Kind_Of
1528 (The_Variable, In_Tree,
1529 To => Expression_Kind_Of (Variable, In_Tree));
1532 if Expression_Kind_Of (The_Variable, In_Tree) /=
1533 Expression_Kind_Of (Variable, In_Tree)
1535 Error_Msg ("wrong expression kind for variable """ &
1537 (Name_Of (The_Variable, In_Tree)) &
1539 Expression_Location);
1547 end Parse_Variable_Declaration;