1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2009, 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 Is_Config_File : Boolean);
68 -- Parse a case construction
70 procedure Parse_Declarative_Items
71 (In_Tree : Project_Node_Tree_Ref;
72 Declarations : out Project_Node_Id;
74 First_Attribute : Attribute_Node_Id;
75 Current_Project : Project_Node_Id;
76 Current_Package : Project_Node_Id;
77 Packages_To_Check : String_List_Access;
78 Is_Config_File : Boolean);
79 -- Parse declarative items. Depending on In_Zone, some declarative
80 -- items may be forbidden.
81 -- Is_Config_File should be set to True if the project represents a config
82 -- file (.cgpr) since some specific checks apply.
84 procedure Parse_Package_Declaration
85 (In_Tree : Project_Node_Tree_Ref;
86 Package_Declaration : out Project_Node_Id;
87 Current_Project : Project_Node_Id;
88 Packages_To_Check : String_List_Access;
89 Is_Config_File : Boolean);
90 -- Parse a package declaration.
91 -- Is_Config_File should be set to True if the project represents a config
92 -- file (.cgpr) since some specific checks apply.
94 procedure Parse_String_Type_Declaration
95 (In_Tree : Project_Node_Tree_Ref;
96 String_Type : out Project_Node_Id;
97 Current_Project : Project_Node_Id);
98 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
100 procedure Parse_Variable_Declaration
101 (In_Tree : Project_Node_Tree_Ref;
102 Variable : out Project_Node_Id;
103 Current_Project : Project_Node_Id;
104 Current_Package : Project_Node_Id);
105 -- Parse a variable assignment
106 -- <variable_Name> := <expression>; OR
107 -- <variable_Name> : <string_type_Name> := <string_expression>;
114 (In_Tree : Project_Node_Tree_Ref;
115 Declarations : out Project_Node_Id;
116 Current_Project : Project_Node_Id;
117 Extends : Project_Node_Id;
118 Packages_To_Check : String_List_Access;
119 Is_Config_File : Boolean)
121 First_Declarative_Item : Project_Node_Id := Empty_Node;
126 (Of_Kind => N_Project_Declaration, In_Tree => In_Tree);
127 Set_Location_Of (Declarations, In_Tree, To => Token_Ptr);
128 Set_Extended_Project_Of (Declarations, In_Tree, To => Extends);
129 Set_Project_Declaration_Of (Current_Project, In_Tree, Declarations);
130 Parse_Declarative_Items
131 (Declarations => First_Declarative_Item,
133 In_Zone => In_Project,
134 First_Attribute => Prj.Attr.Attribute_First,
135 Current_Project => Current_Project,
136 Current_Package => Empty_Node,
137 Packages_To_Check => Packages_To_Check,
138 Is_Config_File => Is_Config_File);
139 Set_First_Declarative_Item_Of
140 (Declarations, In_Tree, To => First_Declarative_Item);
143 ---------------------------------
144 -- Parse_Attribute_Declaration --
145 ---------------------------------
147 procedure Parse_Attribute_Declaration
148 (In_Tree : Project_Node_Tree_Ref;
149 Attribute : out Project_Node_Id;
150 First_Attribute : Attribute_Node_Id;
151 Current_Project : Project_Node_Id;
152 Current_Package : Project_Node_Id;
153 Packages_To_Check : String_List_Access)
155 Current_Attribute : Attribute_Node_Id := First_Attribute;
156 Full_Associative_Array : Boolean := False;
157 Attribute_Name : Name_Id := No_Name;
158 Optional_Index : Boolean := False;
159 Pkg_Id : Package_Node_Id := Empty_Package;
160 Ignore : Boolean := False;
165 (Of_Kind => N_Attribute_Declaration, In_Tree => In_Tree);
166 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
167 Set_Previous_Line_Node (Attribute);
173 -- Body may be an attribute name
175 if Token = Tok_Body then
176 Token := Tok_Identifier;
177 Token_Name := Snames.Name_Body;
180 Expect (Tok_Identifier, "identifier");
182 if Token = Tok_Identifier then
183 Attribute_Name := Token_Name;
184 Set_Name_Of (Attribute, In_Tree, To => Token_Name);
185 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
187 -- Find the attribute
190 Attribute_Node_Id_Of (Token_Name, First_Attribute);
192 -- If the attribute cannot be found, create the attribute if inside
193 -- an unknown package.
195 if Current_Attribute = Empty_Attribute then
196 if Present (Current_Package)
197 and then Expression_Kind_Of (Current_Package, In_Tree) = Ignored
199 Pkg_Id := Package_Id_Of (Current_Package, In_Tree);
200 Add_Attribute (Pkg_Id, Token_Name, Current_Attribute);
203 -- If not a valid attribute name, issue an error if inside
204 -- a package that need to be checked.
206 Ignore := Present (Current_Package) and then
207 Packages_To_Check /= All_Packages;
211 -- Check that we are not in a package to check
213 Get_Name_String (Name_Of (Current_Package, In_Tree));
215 for Index in Packages_To_Check'Range loop
216 if Name_Buffer (1 .. Name_Len) =
217 Packages_To_Check (Index).all
226 Error_Msg_Name_1 := Token_Name;
227 Error_Msg ("undefined attribute %%", Token_Ptr);
231 -- Set, if appropriate the index case insensitivity flag
234 if Is_Read_Only (Current_Attribute) then
235 Error_Msg_Name_1 := Token_Name;
237 ("read-only attribute %% cannot be given a value",
241 if Attribute_Kind_Of (Current_Attribute) in
242 Case_Insensitive_Associative_Array ..
243 Optional_Index_Case_Insensitive_Associative_Array
245 Set_Case_Insensitive (Attribute, In_Tree, To => True);
249 Scan (In_Tree); -- past the attribute name
252 -- Change obsolete names of attributes to the new names
254 if Present (Current_Package)
255 and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored
257 case Name_Of (Attribute, In_Tree) is
258 when Snames.Name_Specification =>
259 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec);
261 when Snames.Name_Specification_Suffix =>
262 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix);
264 when Snames.Name_Implementation =>
265 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body);
267 when Snames.Name_Implementation_Suffix =>
268 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix);
275 -- Associative array attributes
277 if Token = Tok_Left_Paren then
279 -- If the attribute is not an associative array attribute, report
280 -- an error. If this information is still unknown, set the kind
281 -- to Associative_Array.
283 if Current_Attribute /= Empty_Attribute
284 and then Attribute_Kind_Of (Current_Attribute) = Single
286 Error_Msg ("the attribute """ &
288 (Attribute_Name_Of (Current_Attribute)) &
289 """ cannot be an associative array",
290 Location_Of (Attribute, In_Tree));
292 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
293 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
296 Scan (In_Tree); -- past the left parenthesis
298 if Others_Allowed_For (Current_Attribute)
299 and then Token = Tok_Others
301 Set_Associative_Array_Index_Of
302 (Attribute, In_Tree, All_Other_Names);
303 Scan (In_Tree); -- past others
306 if Others_Allowed_For (Current_Attribute) then
307 Expect (Tok_String_Literal, "literal string or others");
309 Expect (Tok_String_Literal, "literal string");
312 if Token = Tok_String_Literal then
313 Get_Name_String (Token_Name);
315 if Case_Insensitive (Attribute, In_Tree) then
316 To_Lower (Name_Buffer (1 .. Name_Len));
319 Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find);
320 Scan (In_Tree); -- past the literal string index
322 if Token = Tok_At then
323 case Attribute_Kind_Of (Current_Attribute) is
324 when Optional_Index_Associative_Array |
325 Optional_Index_Case_Insensitive_Associative_Array =>
327 Expect (Tok_Integer_Literal, "integer literal");
329 if Token = Tok_Integer_Literal then
331 -- Set the source index value from given literal
334 Index : constant Int :=
335 UI_To_Int (Int_Literal_Value);
338 Error_Msg ("index cannot be zero", Token_Ptr);
341 (Attribute, In_Tree, To => Index);
349 Error_Msg ("index not allowed here", Token_Ptr);
352 if Token = Tok_Integer_Literal then
360 Expect (Tok_Right_Paren, "`)`");
362 if Token = Tok_Right_Paren then
363 Scan (In_Tree); -- past the right parenthesis
367 -- If it is an associative array attribute and there are no left
368 -- parenthesis, then this is a full associative array declaration.
369 -- Flag it as such for later processing of its value.
371 if Current_Attribute /= Empty_Attribute
373 Attribute_Kind_Of (Current_Attribute) /= Single
375 if Attribute_Kind_Of (Current_Attribute) = Unknown then
376 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
379 Full_Associative_Array := True;
384 -- Set the expression kind of the attribute
386 if Current_Attribute /= Empty_Attribute then
387 Set_Expression_Kind_Of
388 (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute));
389 Optional_Index := Optional_Index_Of (Current_Attribute);
392 Expect (Tok_Use, "USE");
394 if Token = Tok_Use then
397 if Full_Associative_Array then
399 -- Expect <project>'<same_attribute_name>, or
400 -- <project>.<same_package_name>'<same_attribute_name>
403 The_Project : Project_Node_Id := Empty_Node;
404 -- The node of the project where the associative array is
407 The_Package : Project_Node_Id := Empty_Node;
408 -- The node of the package where the associative array is
411 Project_Name : Name_Id := No_Name;
412 -- The name of the project where the associative array is
415 Location : Source_Ptr := No_Location;
416 -- The location of the project name
419 Expect (Tok_Identifier, "identifier");
421 if Token = Tok_Identifier then
422 Location := Token_Ptr;
424 -- Find the project node in the imported project or
425 -- in the project being extended.
427 The_Project := Imported_Or_Extended_Project_Of
428 (Current_Project, In_Tree, Token_Name);
430 if No (The_Project) then
431 Error_Msg ("unknown project", Location);
432 Scan (In_Tree); -- past the project name
435 Project_Name := Token_Name;
436 Scan (In_Tree); -- past the project name
438 -- If this is inside a package, a dot followed by the
439 -- name of the package must followed the project name.
441 if Present (Current_Package) then
442 Expect (Tok_Dot, "`.`");
444 if Token /= Tok_Dot then
445 The_Project := Empty_Node;
448 Scan (In_Tree); -- past the dot
449 Expect (Tok_Identifier, "identifier");
451 if Token /= Tok_Identifier then
452 The_Project := Empty_Node;
454 -- If it is not the same package name, issue error
457 Token_Name /= Name_Of (Current_Package, In_Tree)
459 The_Project := Empty_Node;
461 ("not the same package as " &
463 (Name_Of (Current_Package, In_Tree)),
468 First_Package_Of (The_Project, In_Tree);
470 -- Look for the package node
472 while Present (The_Package)
474 Name_Of (The_Package, In_Tree) /= Token_Name
477 Next_Package_In_Project
478 (The_Package, In_Tree);
481 -- If the package cannot be found in the
482 -- project, issue an error.
484 if No (The_Package) then
485 The_Project := Empty_Node;
486 Error_Msg_Name_2 := Project_Name;
487 Error_Msg_Name_1 := Token_Name;
489 ("package % not declared in project %",
493 Scan (In_Tree); -- past the package name
500 if Present (The_Project) then
502 -- Looking for '<same attribute name>
504 Expect (Tok_Apostrophe, "`''`");
506 if Token /= Tok_Apostrophe then
507 The_Project := Empty_Node;
510 Scan (In_Tree); -- past the apostrophe
511 Expect (Tok_Identifier, "identifier");
513 if Token /= Tok_Identifier then
514 The_Project := Empty_Node;
517 -- If it is not the same attribute name, issue error
519 if Token_Name /= Attribute_Name then
520 The_Project := Empty_Node;
521 Error_Msg_Name_1 := Attribute_Name;
522 Error_Msg ("invalid name, should be %", Token_Ptr);
525 Scan (In_Tree); -- past the attribute name
530 if No (The_Project) then
532 -- If there were any problem, set the attribute id to null,
533 -- so that the node will not be recorded.
535 Current_Attribute := Empty_Attribute;
538 -- Set the appropriate field in the node.
539 -- Note that the index and the expression are nil. This
540 -- characterizes full associative array attribute
543 Set_Associative_Project_Of (Attribute, In_Tree, The_Project);
544 Set_Associative_Package_Of (Attribute, In_Tree, The_Package);
548 -- Other attribute declarations (not full associative array)
552 Expression_Location : constant Source_Ptr := Token_Ptr;
553 -- The location of the first token of the expression
555 Expression : Project_Node_Id := Empty_Node;
556 -- The expression, value for the attribute declaration
559 -- Get the expression value and set it in the attribute node
563 Expression => Expression,
564 Current_Project => Current_Project,
565 Current_Package => Current_Package,
566 Optional_Index => Optional_Index);
567 Set_Expression_Of (Attribute, In_Tree, To => Expression);
569 -- If the expression is legal, but not of the right kind
570 -- for the attribute, issue an error.
572 if Current_Attribute /= Empty_Attribute
573 and then Present (Expression)
574 and then Variable_Kind_Of (Current_Attribute) /=
575 Expression_Kind_Of (Expression, In_Tree)
577 if Variable_Kind_Of (Current_Attribute) = Undefined then
580 To => Expression_Kind_Of (Expression, In_Tree));
584 ("wrong expression kind for attribute """ &
586 (Attribute_Name_Of (Current_Attribute)) &
588 Expression_Location);
595 -- If the attribute was not recognized, return an empty node.
596 -- It may be that it is not in a package to check, and the node will
597 -- not be added to the tree.
599 if Current_Attribute = Empty_Attribute then
600 Attribute := Empty_Node;
603 Set_End_Of_Line (Attribute);
604 Set_Previous_Line_Node (Attribute);
605 end Parse_Attribute_Declaration;
607 -----------------------------
608 -- Parse_Case_Construction --
609 -----------------------------
611 procedure Parse_Case_Construction
612 (In_Tree : Project_Node_Tree_Ref;
613 Case_Construction : out Project_Node_Id;
614 First_Attribute : Attribute_Node_Id;
615 Current_Project : Project_Node_Id;
616 Current_Package : Project_Node_Id;
617 Packages_To_Check : String_List_Access;
618 Is_Config_File : Boolean)
620 Current_Item : Project_Node_Id := Empty_Node;
621 Next_Item : Project_Node_Id := Empty_Node;
622 First_Case_Item : Boolean := True;
624 Variable_Location : Source_Ptr := No_Location;
626 String_Type : Project_Node_Id := Empty_Node;
628 Case_Variable : Project_Node_Id := Empty_Node;
630 First_Declarative_Item : Project_Node_Id := Empty_Node;
632 First_Choice : Project_Node_Id := Empty_Node;
634 When_Others : Boolean := False;
635 -- Set to True when there is a "when others =>" clause
640 (Of_Kind => N_Case_Construction, In_Tree => In_Tree);
641 Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr);
647 -- Get the switch variable
649 Expect (Tok_Identifier, "identifier");
651 if Token = Tok_Identifier then
652 Variable_Location := Token_Ptr;
653 Parse_Variable_Reference
655 Variable => Case_Variable,
656 Current_Project => Current_Project,
657 Current_Package => Current_Package);
658 Set_Case_Variable_Reference_Of
659 (Case_Construction, In_Tree, To => Case_Variable);
662 if Token /= Tok_Is then
667 if Present (Case_Variable) then
668 String_Type := String_Type_Of (Case_Variable, In_Tree);
670 if No (String_Type) then
671 Error_Msg ("variable """ &
672 Get_Name_String (Name_Of (Case_Variable, In_Tree)) &
678 Expect (Tok_Is, "IS");
680 if Token = Tok_Is then
681 Set_End_Of_Line (Case_Construction);
682 Set_Previous_Line_Node (Case_Construction);
683 Set_Next_End_Node (Case_Construction);
690 Start_New_Case_Construction (In_Tree, String_Type);
694 while Token = Tok_When loop
696 if First_Case_Item then
699 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
700 Set_First_Case_Item_Of
701 (Case_Construction, In_Tree, To => Current_Item);
702 First_Case_Item := False;
707 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
708 Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item);
709 Current_Item := Next_Item;
712 Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr);
718 if Token = Tok_Others then
721 -- Scan past "others"
725 Expect (Tok_Arrow, "`=>`");
726 Set_End_Of_Line (Current_Item);
727 Set_Previous_Line_Node (Current_Item);
729 -- Empty_Node in Field1 of a Case_Item indicates
730 -- the "when others =>" branch.
732 Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node);
734 Parse_Declarative_Items
736 Declarations => First_Declarative_Item,
737 In_Zone => In_Case_Construction,
738 First_Attribute => First_Attribute,
739 Current_Project => Current_Project,
740 Current_Package => Current_Package,
741 Packages_To_Check => Packages_To_Check,
742 Is_Config_File => Is_Config_File);
744 -- "when others =>" must be the last branch, so save the
745 -- Case_Item and exit
747 Set_First_Declarative_Item_Of
748 (Current_Item, In_Tree, To => First_Declarative_Item);
754 First_Choice => First_Choice);
755 Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice);
757 Expect (Tok_Arrow, "`=>`");
758 Set_End_Of_Line (Current_Item);
759 Set_Previous_Line_Node (Current_Item);
761 Parse_Declarative_Items
763 Declarations => First_Declarative_Item,
764 In_Zone => In_Case_Construction,
765 First_Attribute => First_Attribute,
766 Current_Project => Current_Project,
767 Current_Package => Current_Package,
768 Packages_To_Check => Packages_To_Check,
769 Is_Config_File => Is_Config_File);
771 Set_First_Declarative_Item_Of
772 (Current_Item, In_Tree, To => First_Declarative_Item);
777 End_Case_Construction
778 (Check_All_Labels => not When_Others and not Quiet_Output,
779 Case_Location => Location_Of (Case_Construction, In_Tree));
781 Expect (Tok_End, "`END CASE`");
782 Remove_Next_End_Node;
784 if Token = Tok_End then
790 Expect (Tok_Case, "CASE");
798 Expect (Tok_Semicolon, "`;`");
799 Set_Previous_End_Node (Case_Construction);
801 end Parse_Case_Construction;
803 -----------------------------
804 -- Parse_Declarative_Items --
805 -----------------------------
807 procedure Parse_Declarative_Items
808 (In_Tree : Project_Node_Tree_Ref;
809 Declarations : out Project_Node_Id;
811 First_Attribute : Attribute_Node_Id;
812 Current_Project : Project_Node_Id;
813 Current_Package : Project_Node_Id;
814 Packages_To_Check : String_List_Access;
815 Is_Config_File : Boolean)
817 Current_Declarative_Item : Project_Node_Id := Empty_Node;
818 Next_Declarative_Item : Project_Node_Id := Empty_Node;
819 Current_Declaration : Project_Node_Id := Empty_Node;
820 Item_Location : Source_Ptr := No_Location;
823 Declarations := Empty_Node;
826 -- We are always positioned at the token that precedes the first
827 -- token of the declarative element. Scan past it.
831 Item_Location := Token_Ptr;
834 when Tok_Identifier =>
836 if In_Zone = In_Case_Construction then
838 -- Check if the variable has already been declared
841 The_Variable : Project_Node_Id := Empty_Node;
844 if Present (Current_Package) then
846 First_Variable_Of (Current_Package, In_Tree);
847 elsif Present (Current_Project) then
849 First_Variable_Of (Current_Project, In_Tree);
852 while Present (The_Variable)
853 and then Name_Of (The_Variable, In_Tree) /=
856 The_Variable := Next_Variable (The_Variable, In_Tree);
859 -- It is an error to declare a variable in a case
860 -- construction for the first time.
862 if No (The_Variable) then
864 ("a variable cannot be declared " &
865 "for the first time here",
871 Parse_Variable_Declaration
874 Current_Project => Current_Project,
875 Current_Package => Current_Package);
877 Set_End_Of_Line (Current_Declaration);
878 Set_Previous_Line_Node (Current_Declaration);
882 Parse_Attribute_Declaration
884 Attribute => Current_Declaration,
885 First_Attribute => First_Attribute,
886 Current_Project => Current_Project,
887 Current_Package => Current_Package,
888 Packages_To_Check => Packages_To_Check);
890 Set_End_Of_Line (Current_Declaration);
891 Set_Previous_Line_Node (Current_Declaration);
895 Scan (In_Tree); -- past "null"
899 -- Package declaration
901 if In_Zone /= In_Project then
902 Error_Msg ("a package cannot be declared here", Token_Ptr);
905 Parse_Package_Declaration
907 Package_Declaration => Current_Declaration,
908 Current_Project => Current_Project,
909 Packages_To_Check => Packages_To_Check,
910 Is_Config_File => Is_Config_File);
912 Set_Previous_End_Node (Current_Declaration);
916 -- Type String Declaration
918 if In_Zone /= In_Project then
919 Error_Msg ("a string type cannot be declared here",
923 Parse_String_Type_Declaration
925 String_Type => Current_Declaration,
926 Current_Project => Current_Project);
928 Set_End_Of_Line (Current_Declaration);
929 Set_Previous_Line_Node (Current_Declaration);
935 Parse_Case_Construction
937 Case_Construction => Current_Declaration,
938 First_Attribute => First_Attribute,
939 Current_Project => Current_Project,
940 Current_Package => Current_Package,
941 Packages_To_Check => Packages_To_Check,
942 Is_Config_File => Is_Config_File);
944 Set_Previous_End_Node (Current_Declaration);
949 -- We are leaving Parse_Declarative_Items positioned
950 -- at the first token after the list of declarative items.
951 -- It could be "end" (for a project, a package declaration or
952 -- a case construction) or "when" (for a case construction)
956 Expect (Tok_Semicolon, "`;` after declarative items");
958 -- Insert an N_Declarative_Item in the tree, but only if
959 -- Current_Declaration is not an empty node.
961 if Present (Current_Declaration) then
962 if No (Current_Declarative_Item) then
963 Current_Declarative_Item :=
965 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
966 Declarations := Current_Declarative_Item;
969 Next_Declarative_Item :=
971 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
972 Set_Next_Declarative_Item
973 (Current_Declarative_Item, In_Tree,
974 To => Next_Declarative_Item);
975 Current_Declarative_Item := Next_Declarative_Item;
978 Set_Current_Item_Node
979 (Current_Declarative_Item, In_Tree,
980 To => Current_Declaration);
982 (Current_Declarative_Item, In_Tree, To => Item_Location);
985 end Parse_Declarative_Items;
987 -------------------------------
988 -- Parse_Package_Declaration --
989 -------------------------------
991 procedure Parse_Package_Declaration
992 (In_Tree : Project_Node_Tree_Ref;
993 Package_Declaration : out Project_Node_Id;
994 Current_Project : Project_Node_Id;
995 Packages_To_Check : String_List_Access;
996 Is_Config_File : Boolean)
998 First_Attribute : Attribute_Node_Id := Empty_Attribute;
999 Current_Package : Package_Node_Id := Empty_Package;
1000 First_Declarative_Item : Project_Node_Id := Empty_Node;
1002 Package_Location : constant Source_Ptr := Token_Ptr;
1005 Package_Declaration :=
1006 Default_Project_Node
1007 (Of_Kind => N_Package_Declaration, In_Tree => In_Tree);
1008 Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location);
1010 -- Scan past "package"
1013 Expect (Tok_Identifier, "identifier");
1015 if Token = Tok_Identifier then
1016 Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name);
1018 Current_Package := Package_Node_Id_Of (Token_Name);
1020 if Current_Package = Empty_Package then
1021 if not Quiet_Output then
1023 List : constant Strings.String_List := Package_Name_List;
1025 Name : constant String := Get_Name_String (Token_Name);
1028 -- Check for possible misspelling of a known package name
1032 if Index >= List'Last then
1039 GNAT.Spelling_Checker.Is_Bad_Spelling_Of
1040 (Name, List (Index).all);
1043 -- Issue warning(s) in verbose mode or when a possible
1044 -- misspelling has been found.
1046 if Verbose_Mode or else Index /= 0 then
1049 (Name_Of (Package_Declaration, In_Tree)) &
1050 """ is not a known package name",
1055 Error_Msg -- CODEFIX
1056 ("\?possible misspelling of """ &
1057 List (Index).all & """", Token_Ptr);
1062 -- Set the package declaration to "ignored" so that it is not
1063 -- processed by Prj.Proc.Process.
1065 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1067 -- Add the unknown package in the list of packages
1069 Add_Unknown_Package (Token_Name, Current_Package);
1071 elsif Current_Package = Unknown_Package then
1073 -- Set the package declaration to "ignored" so that it is not
1074 -- processed by Prj.Proc.Process.
1076 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1079 First_Attribute := First_Attribute_Of (Current_Package);
1083 (Package_Declaration, In_Tree, To => Current_Package);
1086 Current : Project_Node_Id :=
1087 First_Package_Of (Current_Project, In_Tree);
1090 while Present (Current)
1091 and then Name_Of (Current, In_Tree) /= Token_Name
1093 Current := Next_Package_In_Project (Current, In_Tree);
1096 if Present (Current) then
1099 Get_Name_String (Name_Of (Package_Declaration, In_Tree)) &
1100 """ is declared twice in the same project",
1104 -- Add the package to the project list
1106 Set_Next_Package_In_Project
1107 (Package_Declaration, In_Tree,
1108 To => First_Package_Of (Current_Project, In_Tree));
1109 Set_First_Package_Of
1110 (Current_Project, In_Tree, To => Package_Declaration);
1114 -- Scan past the package name
1119 if Token = Tok_Renames then
1120 if Is_Config_File then
1122 ("no package renames in configuration projects", Token_Ptr);
1125 -- Scan past "renames"
1129 Expect (Tok_Identifier, "identifier");
1131 if Token = Tok_Identifier then
1133 Project_Name : constant Name_Id := Token_Name;
1135 Clause : Project_Node_Id :=
1136 First_With_Clause_Of (Current_Project, In_Tree);
1137 The_Project : Project_Node_Id := Empty_Node;
1138 Extended : constant Project_Node_Id :=
1140 (Project_Declaration_Of
1141 (Current_Project, In_Tree),
1144 while Present (Clause) loop
1145 -- Only non limited imported projects may be used in a
1146 -- renames declaration.
1149 Non_Limited_Project_Node_Of (Clause, In_Tree);
1150 exit when Present (The_Project)
1151 and then Name_Of (The_Project, In_Tree) = Project_Name;
1152 Clause := Next_With_Clause_Of (Clause, In_Tree);
1156 -- As we have not found the project in the imports, we check
1157 -- if it's the name of an eventual extended project.
1159 if Present (Extended)
1160 and then Name_Of (Extended, In_Tree) = Project_Name
1162 Set_Project_Of_Renamed_Package_Of
1163 (Package_Declaration, In_Tree, To => Extended);
1165 Error_Msg_Name_1 := Project_Name;
1167 ("% is not an imported or extended project", Token_Ptr);
1170 Set_Project_Of_Renamed_Package_Of
1171 (Package_Declaration, In_Tree, To => The_Project);
1176 Expect (Tok_Dot, "`.`");
1178 if Token = Tok_Dot then
1180 Expect (Tok_Identifier, "identifier");
1182 if Token = Tok_Identifier then
1183 if Name_Of (Package_Declaration, In_Tree) /= Token_Name then
1184 Error_Msg ("not the same package name", Token_Ptr);
1186 Present (Project_Of_Renamed_Package_Of
1187 (Package_Declaration, In_Tree))
1190 Current : Project_Node_Id :=
1192 (Project_Of_Renamed_Package_Of
1193 (Package_Declaration, In_Tree),
1197 while Present (Current)
1198 and then Name_Of (Current, In_Tree) /= Token_Name
1201 Next_Package_In_Project (Current, In_Tree);
1204 if No (Current) then
1207 Get_Name_String (Token_Name) &
1208 """ is not a package declared by the project",
1219 Expect (Tok_Semicolon, "`;`");
1220 Set_End_Of_Line (Package_Declaration);
1221 Set_Previous_Line_Node (Package_Declaration);
1223 elsif Token = Tok_Is then
1224 Set_End_Of_Line (Package_Declaration);
1225 Set_Previous_Line_Node (Package_Declaration);
1226 Set_Next_End_Node (Package_Declaration);
1228 Parse_Declarative_Items
1229 (In_Tree => In_Tree,
1230 Declarations => First_Declarative_Item,
1231 In_Zone => In_Package,
1232 First_Attribute => First_Attribute,
1233 Current_Project => Current_Project,
1234 Current_Package => Package_Declaration,
1235 Packages_To_Check => Packages_To_Check,
1236 Is_Config_File => Is_Config_File);
1238 Set_First_Declarative_Item_Of
1239 (Package_Declaration, In_Tree, To => First_Declarative_Item);
1241 Expect (Tok_End, "END");
1243 if Token = Tok_End then
1250 -- We should have the name of the package after "end"
1252 Expect (Tok_Identifier, "identifier");
1254 if Token = Tok_Identifier
1255 and then Name_Of (Package_Declaration, In_Tree) /= No_Name
1256 and then Token_Name /= Name_Of (Package_Declaration, In_Tree)
1258 Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree);
1259 Error_Msg ("expected %%", Token_Ptr);
1262 if Token /= Tok_Semicolon then
1264 -- Scan past the package name
1269 Expect (Tok_Semicolon, "`;`");
1270 Remove_Next_End_Node;
1273 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1276 end Parse_Package_Declaration;
1278 -----------------------------------
1279 -- Parse_String_Type_Declaration --
1280 -----------------------------------
1282 procedure Parse_String_Type_Declaration
1283 (In_Tree : Project_Node_Tree_Ref;
1284 String_Type : out Project_Node_Id;
1285 Current_Project : Project_Node_Id)
1287 Current : Project_Node_Id := Empty_Node;
1288 First_String : Project_Node_Id := Empty_Node;
1292 Default_Project_Node
1293 (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree);
1295 Set_Location_Of (String_Type, In_Tree, To => Token_Ptr);
1301 Expect (Tok_Identifier, "identifier");
1303 if Token = Tok_Identifier then
1304 Set_Name_Of (String_Type, In_Tree, To => Token_Name);
1306 Current := First_String_Type_Of (Current_Project, In_Tree);
1307 while Present (Current)
1309 Name_Of (Current, In_Tree) /= Token_Name
1311 Current := Next_String_Type (Current, In_Tree);
1314 if Present (Current) then
1315 Error_Msg ("duplicate string type name """ &
1316 Get_Name_String (Token_Name) &
1320 Current := First_Variable_Of (Current_Project, In_Tree);
1321 while Present (Current)
1322 and then Name_Of (Current, In_Tree) /= Token_Name
1324 Current := Next_Variable (Current, In_Tree);
1327 if Present (Current) then
1329 Get_Name_String (Token_Name) &
1330 """ is already a variable name", Token_Ptr);
1332 Set_Next_String_Type
1333 (String_Type, In_Tree,
1334 To => First_String_Type_Of (Current_Project, In_Tree));
1335 Set_First_String_Type_Of
1336 (Current_Project, In_Tree, To => String_Type);
1340 -- Scan past the name
1345 Expect (Tok_Is, "IS");
1347 if Token = Tok_Is then
1351 Expect (Tok_Left_Paren, "`(`");
1353 if Token = Tok_Left_Paren then
1357 Parse_String_Type_List
1358 (In_Tree => In_Tree, First_String => First_String);
1359 Set_First_Literal_String (String_Type, In_Tree, To => First_String);
1361 Expect (Tok_Right_Paren, "`)`");
1363 if Token = Tok_Right_Paren then
1367 end Parse_String_Type_Declaration;
1369 --------------------------------
1370 -- Parse_Variable_Declaration --
1371 --------------------------------
1373 procedure Parse_Variable_Declaration
1374 (In_Tree : Project_Node_Tree_Ref;
1375 Variable : out Project_Node_Id;
1376 Current_Project : Project_Node_Id;
1377 Current_Package : Project_Node_Id)
1379 Expression_Location : Source_Ptr;
1380 String_Type_Name : Name_Id := No_Name;
1381 Project_String_Type_Name : Name_Id := No_Name;
1382 Type_Location : Source_Ptr := No_Location;
1383 Project_Location : Source_Ptr := No_Location;
1384 Expression : Project_Node_Id := Empty_Node;
1385 Variable_Name : constant Name_Id := Token_Name;
1386 OK : Boolean := True;
1390 Default_Project_Node
1391 (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree);
1392 Set_Name_Of (Variable, In_Tree, To => Variable_Name);
1393 Set_Location_Of (Variable, In_Tree, To => Token_Ptr);
1395 -- Scan past the variable name
1399 if Token = Tok_Colon then
1401 -- Typed string variable declaration
1404 Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration);
1405 Expect (Tok_Identifier, "identifier");
1407 OK := Token = Tok_Identifier;
1410 String_Type_Name := Token_Name;
1411 Type_Location := Token_Ptr;
1414 if Token = Tok_Dot then
1415 Project_String_Type_Name := String_Type_Name;
1416 Project_Location := Type_Location;
1418 -- Scan past the dot
1421 Expect (Tok_Identifier, "identifier");
1423 if Token = Tok_Identifier then
1424 String_Type_Name := Token_Name;
1425 Type_Location := Token_Ptr;
1434 Proj : Project_Node_Id := Current_Project;
1435 Current : Project_Node_Id := Empty_Node;
1438 if Project_String_Type_Name /= No_Name then
1440 The_Project_Name_And_Node : constant
1441 Tree_Private_Part.Project_Name_And_Node :=
1442 Tree_Private_Part.Projects_Htable.Get
1443 (In_Tree.Projects_HT, Project_String_Type_Name);
1445 use Tree_Private_Part;
1448 if The_Project_Name_And_Node =
1449 Tree_Private_Part.No_Project_Name_And_Node
1451 Error_Msg ("unknown project """ &
1453 (Project_String_Type_Name) &
1456 Current := Empty_Node;
1459 First_String_Type_Of
1460 (The_Project_Name_And_Node.Node, In_Tree);
1464 Name_Of (Current, In_Tree) /= String_Type_Name
1466 Current := Next_String_Type (Current, In_Tree);
1472 -- Look for a string type with the correct name in this
1473 -- project or in any of its ancestors.
1477 First_String_Type_Of (Proj, In_Tree);
1481 Name_Of (Current, In_Tree) /= String_Type_Name
1483 Current := Next_String_Type (Current, In_Tree);
1486 exit when Present (Current);
1488 Proj := Parent_Project_Of (Proj, In_Tree);
1489 exit when No (Proj);
1493 if No (Current) then
1494 Error_Msg ("unknown string type """ &
1495 Get_Name_String (String_Type_Name) &
1502 (Variable, In_Tree, To => Current);
1509 Expect (Tok_Colon_Equal, "`:=`");
1511 OK := OK and (Token = Tok_Colon_Equal);
1513 if Token = Tok_Colon_Equal then
1517 -- Get the single string or string list value
1519 Expression_Location := Token_Ptr;
1522 (In_Tree => In_Tree,
1523 Expression => Expression,
1524 Current_Project => Current_Project,
1525 Current_Package => Current_Package,
1526 Optional_Index => False);
1527 Set_Expression_Of (Variable, In_Tree, To => Expression);
1529 if Present (Expression) then
1530 -- A typed string must have a single string value, not a list
1532 if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration
1533 and then Expression_Kind_Of (Expression, In_Tree) = List
1536 ("expression must be a single string", Expression_Location);
1539 Set_Expression_Kind_Of
1541 To => Expression_Kind_Of (Expression, In_Tree));
1546 The_Variable : Project_Node_Id := Empty_Node;
1549 if Present (Current_Package) then
1550 The_Variable := First_Variable_Of (Current_Package, In_Tree);
1551 elsif Present (Current_Project) then
1552 The_Variable := First_Variable_Of (Current_Project, In_Tree);
1555 while Present (The_Variable)
1556 and then Name_Of (The_Variable, In_Tree) /= Variable_Name
1558 The_Variable := Next_Variable (The_Variable, In_Tree);
1561 if No (The_Variable) then
1562 if Present (Current_Package) then
1565 To => First_Variable_Of (Current_Package, In_Tree));
1566 Set_First_Variable_Of
1567 (Current_Package, In_Tree, To => Variable);
1569 elsif Present (Current_Project) then
1572 To => First_Variable_Of (Current_Project, In_Tree));
1573 Set_First_Variable_Of
1574 (Current_Project, In_Tree, To => Variable);
1578 if Expression_Kind_Of (Variable, In_Tree) /= Undefined then
1579 if Expression_Kind_Of (The_Variable, In_Tree) =
1582 Set_Expression_Kind_Of
1583 (The_Variable, In_Tree,
1584 To => Expression_Kind_Of (Variable, In_Tree));
1587 if Expression_Kind_Of (The_Variable, In_Tree) /=
1588 Expression_Kind_Of (Variable, In_Tree)
1590 Error_Msg ("wrong expression kind for variable """ &
1592 (Name_Of (The_Variable, In_Tree)) &
1594 Expression_Location);
1601 end Parse_Variable_Declaration;