1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2007, 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Err_Vars; use Err_Vars;
29 with GNAT.Case_Util; use GNAT.Case_Util;
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;
40 package body Prj.Dect is
42 type Zone is (In_Project, In_Package, In_Case_Construction);
43 -- Used to indicate if we are parsing a package (In_Package),
44 -- a case construction (In_Case_Construction) or none of those two
47 procedure Parse_Attribute_Declaration
48 (In_Tree : Project_Node_Tree_Ref;
49 Attribute : out Project_Node_Id;
50 First_Attribute : Attribute_Node_Id;
51 Current_Project : Project_Node_Id;
52 Current_Package : Project_Node_Id;
53 Packages_To_Check : String_List_Access);
54 -- Parse an attribute declaration
56 procedure Parse_Case_Construction
57 (In_Tree : Project_Node_Tree_Ref;
58 Case_Construction : out Project_Node_Id;
59 First_Attribute : Attribute_Node_Id;
60 Current_Project : Project_Node_Id;
61 Current_Package : Project_Node_Id;
62 Packages_To_Check : String_List_Access);
63 -- Parse a case construction
65 procedure Parse_Declarative_Items
66 (In_Tree : Project_Node_Tree_Ref;
67 Declarations : out Project_Node_Id;
69 First_Attribute : Attribute_Node_Id;
70 Current_Project : Project_Node_Id;
71 Current_Package : Project_Node_Id;
72 Packages_To_Check : String_List_Access);
73 -- Parse declarative items. Depending on In_Zone, some declarative
74 -- items may be forbiden.
76 procedure Parse_Package_Declaration
77 (In_Tree : Project_Node_Tree_Ref;
78 Package_Declaration : out Project_Node_Id;
79 Current_Project : Project_Node_Id;
80 Packages_To_Check : String_List_Access);
81 -- Parse a package declaration
83 procedure Parse_String_Type_Declaration
84 (In_Tree : Project_Node_Tree_Ref;
85 String_Type : out Project_Node_Id;
86 Current_Project : Project_Node_Id);
87 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
89 procedure Parse_Variable_Declaration
90 (In_Tree : Project_Node_Tree_Ref;
91 Variable : out Project_Node_Id;
92 Current_Project : Project_Node_Id;
93 Current_Package : Project_Node_Id);
94 -- Parse a variable assignment
95 -- <variable_Name> := <expression>; OR
96 -- <variable_Name> : <string_type_Name> := <string_expression>;
103 (In_Tree : Project_Node_Tree_Ref;
104 Declarations : out Project_Node_Id;
105 Current_Project : Project_Node_Id;
106 Extends : Project_Node_Id;
107 Packages_To_Check : String_List_Access)
109 First_Declarative_Item : Project_Node_Id := Empty_Node;
114 (Of_Kind => N_Project_Declaration, In_Tree => In_Tree);
115 Set_Location_Of (Declarations, In_Tree, To => Token_Ptr);
116 Set_Extended_Project_Of (Declarations, In_Tree, To => Extends);
117 Set_Project_Declaration_Of (Current_Project, In_Tree, Declarations);
118 Parse_Declarative_Items
119 (Declarations => First_Declarative_Item,
121 In_Zone => In_Project,
122 First_Attribute => Prj.Attr.Attribute_First,
123 Current_Project => Current_Project,
124 Current_Package => Empty_Node,
125 Packages_To_Check => Packages_To_Check);
126 Set_First_Declarative_Item_Of
127 (Declarations, In_Tree, To => First_Declarative_Item);
130 ---------------------------------
131 -- Parse_Attribute_Declaration --
132 ---------------------------------
134 procedure Parse_Attribute_Declaration
135 (In_Tree : Project_Node_Tree_Ref;
136 Attribute : out Project_Node_Id;
137 First_Attribute : Attribute_Node_Id;
138 Current_Project : Project_Node_Id;
139 Current_Package : Project_Node_Id;
140 Packages_To_Check : String_List_Access)
142 Current_Attribute : Attribute_Node_Id := First_Attribute;
143 Full_Associative_Array : Boolean := False;
144 Attribute_Name : Name_Id := No_Name;
145 Optional_Index : Boolean := False;
146 Pkg_Id : Package_Node_Id := Empty_Package;
147 Ignore : Boolean := False;
152 (Of_Kind => N_Attribute_Declaration, In_Tree => In_Tree);
153 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
154 Set_Previous_Line_Node (Attribute);
160 -- Body may be an attribute name
162 if Token = Tok_Body then
163 Token := Tok_Identifier;
164 Token_Name := Snames.Name_Body;
167 Expect (Tok_Identifier, "identifier");
169 if Token = Tok_Identifier then
170 Attribute_Name := Token_Name;
171 Set_Name_Of (Attribute, In_Tree, To => Token_Name);
172 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
174 -- Find the attribute
177 Attribute_Node_Id_Of (Token_Name, First_Attribute);
179 -- If the attribute cannot be found, create the attribute if inside
180 -- an unknown package.
182 if Current_Attribute = Empty_Attribute then
183 if Current_Package /= Empty_Node
184 and then Expression_Kind_Of (Current_Package, In_Tree) = Ignored
186 Pkg_Id := Package_Id_Of (Current_Package, In_Tree);
187 Add_Attribute (Pkg_Id, Token_Name, Current_Attribute);
190 -- If not a valid attribute name, issue an error if inside
191 -- a package that need to be checked.
193 Ignore := Current_Package /= Empty_Node and then
194 Packages_To_Check /= All_Packages;
198 -- Check that we are not in a package to check
200 Get_Name_String (Name_Of (Current_Package, In_Tree));
202 for Index in Packages_To_Check'Range loop
203 if Name_Buffer (1 .. Name_Len) =
204 Packages_To_Check (Index).all
213 Error_Msg_Name_1 := Token_Name;
214 Error_Msg ("undefined attribute %%", Token_Ptr);
218 -- Set, if appropriate the index case insensitivity flag
221 if Is_Read_Only (Current_Attribute) then
223 ("read-only attribute cannot be given a value",
227 if Attribute_Kind_Of (Current_Attribute) in
228 Case_Insensitive_Associative_Array ..
229 Optional_Index_Case_Insensitive_Associative_Array
231 Set_Case_Insensitive (Attribute, In_Tree, To => True);
235 Scan (In_Tree); -- past the attribute name
238 -- Change obsolete names of attributes to the new names
240 if Current_Package /= Empty_Node
241 and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored
243 case Name_Of (Attribute, In_Tree) is
244 when Snames.Name_Specification =>
245 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec);
247 when Snames.Name_Specification_Suffix =>
248 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix);
250 when Snames.Name_Implementation =>
251 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body);
253 when Snames.Name_Implementation_Suffix =>
254 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix);
261 -- Associative array attributes
263 if Token = Tok_Left_Paren then
265 -- If the attribute is not an associative array attribute, report
266 -- an error. If this information is still unknown, set the kind
267 -- to Associative_Array.
269 if Current_Attribute /= Empty_Attribute
270 and then Attribute_Kind_Of (Current_Attribute) = Single
272 Error_Msg ("the attribute """ &
274 (Attribute_Name_Of (Current_Attribute)) &
275 """ cannot be an associative array",
276 Location_Of (Attribute, In_Tree));
278 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
279 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
282 Scan (In_Tree); -- past the left parenthesis
283 Expect (Tok_String_Literal, "literal string");
285 if Token = Tok_String_Literal then
286 Get_Name_String (Token_Name);
288 if Case_Insensitive (Attribute, In_Tree) then
289 To_Lower (Name_Buffer (1 .. Name_Len));
292 Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find);
293 Scan (In_Tree); -- past the literal string index
295 if Token = Tok_At then
296 case Attribute_Kind_Of (Current_Attribute) is
297 when Optional_Index_Associative_Array |
298 Optional_Index_Case_Insensitive_Associative_Array =>
300 Expect (Tok_Integer_Literal, "integer literal");
302 if Token = Tok_Integer_Literal then
304 -- Set the source index value from given literal
307 Index : constant Int :=
308 UI_To_Int (Int_Literal_Value);
311 Error_Msg ("index cannot be zero", Token_Ptr);
314 (Attribute, In_Tree, To => Index);
322 Error_Msg ("index not allowed here", Token_Ptr);
325 if Token = Tok_Integer_Literal then
332 Expect (Tok_Right_Paren, "`)`");
334 if Token = Tok_Right_Paren then
335 Scan (In_Tree); -- past the right parenthesis
339 -- If it is an associative array attribute and there are no left
340 -- parenthesis, then this is a full associative array declaration.
341 -- Flag it as such for later processing of its value.
343 if Current_Attribute /= Empty_Attribute
345 Attribute_Kind_Of (Current_Attribute) /= Single
347 if Attribute_Kind_Of (Current_Attribute) = Unknown then
348 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
351 Full_Associative_Array := True;
356 -- Set the expression kind of the attribute
358 if Current_Attribute /= Empty_Attribute then
359 Set_Expression_Kind_Of
360 (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute));
361 Optional_Index := Optional_Index_Of (Current_Attribute);
364 Expect (Tok_Use, "USE");
366 if Token = Tok_Use then
369 if Full_Associative_Array then
371 -- Expect <project>'<same_attribute_name>, or
372 -- <project>.<same_package_name>'<same_attribute_name>
375 The_Project : Project_Node_Id := Empty_Node;
376 -- The node of the project where the associative array is
379 The_Package : Project_Node_Id := Empty_Node;
380 -- The node of the package where the associative array is
383 Project_Name : Name_Id := No_Name;
384 -- The name of the project where the associative array is
387 Location : Source_Ptr := No_Location;
388 -- The location of the project name
391 Expect (Tok_Identifier, "identifier");
393 if Token = Tok_Identifier then
394 Location := Token_Ptr;
396 -- Find the project node in the imported project or
397 -- in the project being extended.
399 The_Project := Imported_Or_Extended_Project_Of
400 (Current_Project, In_Tree, Token_Name);
402 if The_Project = Empty_Node then
403 Error_Msg ("unknown project", Location);
404 Scan (In_Tree); -- past the project name
407 Project_Name := Token_Name;
408 Scan (In_Tree); -- past the project name
410 -- If this is inside a package, a dot followed by the
411 -- name of the package must followed the project name.
413 if Current_Package /= Empty_Node then
414 Expect (Tok_Dot, "`.`");
416 if Token /= Tok_Dot then
417 The_Project := Empty_Node;
420 Scan (In_Tree); -- past the dot
421 Expect (Tok_Identifier, "identifier");
423 if Token /= Tok_Identifier then
424 The_Project := Empty_Node;
426 -- If it is not the same package name, issue error
429 Token_Name /= Name_Of (Current_Package, In_Tree)
431 The_Project := Empty_Node;
433 ("not the same package as " &
435 (Name_Of (Current_Package, In_Tree)),
440 First_Package_Of (The_Project, In_Tree);
442 -- Look for the package node
444 while The_Package /= Empty_Node
446 Name_Of (The_Package, In_Tree) /= Token_Name
449 Next_Package_In_Project
450 (The_Package, In_Tree);
453 -- If the package cannot be found in the
454 -- project, issue an error.
456 if The_Package = Empty_Node then
457 The_Project := Empty_Node;
458 Error_Msg_Name_2 := Project_Name;
459 Error_Msg_Name_1 := Token_Name;
461 ("package % not declared in project %",
465 Scan (In_Tree); -- past the package name
472 if The_Project /= Empty_Node then
474 -- Looking for '<same attribute name>
476 Expect (Tok_Apostrophe, "`''`");
478 if Token /= Tok_Apostrophe then
479 The_Project := Empty_Node;
482 Scan (In_Tree); -- past the apostrophe
483 Expect (Tok_Identifier, "identifier");
485 if Token /= Tok_Identifier then
486 The_Project := Empty_Node;
489 -- If it is not the same attribute name, issue error
491 if Token_Name /= Attribute_Name then
492 The_Project := Empty_Node;
493 Error_Msg_Name_1 := Attribute_Name;
494 Error_Msg ("invalid name, should be %", Token_Ptr);
497 Scan (In_Tree); -- past the attribute name
502 if The_Project = Empty_Node then
504 -- If there were any problem, set the attribute id to null,
505 -- so that the node will not be recorded.
507 Current_Attribute := Empty_Attribute;
510 -- Set the appropriate field in the node.
511 -- Note that the index and the expression are nil. This
512 -- characterizes full associative array attribute
515 Set_Associative_Project_Of (Attribute, In_Tree, The_Project);
516 Set_Associative_Package_Of (Attribute, In_Tree, The_Package);
520 -- Other attribute declarations (not full associative array)
524 Expression_Location : constant Source_Ptr := Token_Ptr;
525 -- The location of the first token of the expression
527 Expression : Project_Node_Id := Empty_Node;
528 -- The expression, value for the attribute declaration
531 -- Get the expression value and set it in the attribute node
535 Expression => Expression,
536 Current_Project => Current_Project,
537 Current_Package => Current_Package,
538 Optional_Index => Optional_Index);
539 Set_Expression_Of (Attribute, In_Tree, To => Expression);
541 -- If the expression is legal, but not of the right kind
542 -- for the attribute, issue an error.
544 if Current_Attribute /= Empty_Attribute
545 and then Expression /= Empty_Node
546 and then Variable_Kind_Of (Current_Attribute) /=
547 Expression_Kind_Of (Expression, In_Tree)
549 if Variable_Kind_Of (Current_Attribute) = Undefined then
552 To => Expression_Kind_Of (Expression, In_Tree));
556 ("wrong expression kind for attribute """ &
558 (Attribute_Name_Of (Current_Attribute)) &
560 Expression_Location);
567 -- If the attribute was not recognized, return an empty node.
568 -- It may be that it is not in a package to check, and the node will
569 -- not be added to the tree.
571 if Current_Attribute = Empty_Attribute then
572 Attribute := Empty_Node;
575 Set_End_Of_Line (Attribute);
576 Set_Previous_Line_Node (Attribute);
577 end Parse_Attribute_Declaration;
579 -----------------------------
580 -- Parse_Case_Construction --
581 -----------------------------
583 procedure Parse_Case_Construction
584 (In_Tree : Project_Node_Tree_Ref;
585 Case_Construction : out Project_Node_Id;
586 First_Attribute : Attribute_Node_Id;
587 Current_Project : Project_Node_Id;
588 Current_Package : Project_Node_Id;
589 Packages_To_Check : String_List_Access)
591 Current_Item : Project_Node_Id := Empty_Node;
592 Next_Item : Project_Node_Id := Empty_Node;
593 First_Case_Item : Boolean := True;
595 Variable_Location : Source_Ptr := No_Location;
597 String_Type : Project_Node_Id := Empty_Node;
599 Case_Variable : Project_Node_Id := Empty_Node;
601 First_Declarative_Item : Project_Node_Id := Empty_Node;
603 First_Choice : Project_Node_Id := Empty_Node;
605 When_Others : Boolean := False;
606 -- Set to True when there is a "when others =>" clause
611 (Of_Kind => N_Case_Construction, In_Tree => In_Tree);
612 Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr);
618 -- Get the switch variable
620 Expect (Tok_Identifier, "identifier");
622 if Token = Tok_Identifier then
623 Variable_Location := Token_Ptr;
624 Parse_Variable_Reference
626 Variable => Case_Variable,
627 Current_Project => Current_Project,
628 Current_Package => Current_Package);
629 Set_Case_Variable_Reference_Of
630 (Case_Construction, In_Tree, To => Case_Variable);
633 if Token /= Tok_Is then
638 if Case_Variable /= Empty_Node then
639 String_Type := String_Type_Of (Case_Variable, In_Tree);
641 if String_Type = Empty_Node then
642 Error_Msg ("variable """ &
643 Get_Name_String (Name_Of (Case_Variable, In_Tree)) &
649 Expect (Tok_Is, "IS");
651 if Token = Tok_Is then
652 Set_End_Of_Line (Case_Construction);
653 Set_Previous_Line_Node (Case_Construction);
654 Set_Next_End_Node (Case_Construction);
661 Start_New_Case_Construction (In_Tree, String_Type);
665 while Token = Tok_When loop
667 if First_Case_Item then
670 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
671 Set_First_Case_Item_Of
672 (Case_Construction, In_Tree, To => Current_Item);
673 First_Case_Item := False;
678 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
679 Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item);
680 Current_Item := Next_Item;
683 Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr);
689 if Token = Tok_Others then
692 -- Scan past "others"
696 Expect (Tok_Arrow, "`=>`");
697 Set_End_Of_Line (Current_Item);
698 Set_Previous_Line_Node (Current_Item);
700 -- Empty_Node in Field1 of a Case_Item indicates
701 -- the "when others =>" branch.
703 Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node);
705 Parse_Declarative_Items
707 Declarations => First_Declarative_Item,
708 In_Zone => In_Case_Construction,
709 First_Attribute => First_Attribute,
710 Current_Project => Current_Project,
711 Current_Package => Current_Package,
712 Packages_To_Check => Packages_To_Check);
714 -- "when others =>" must be the last branch, so save the
715 -- Case_Item and exit
717 Set_First_Declarative_Item_Of
718 (Current_Item, In_Tree, To => First_Declarative_Item);
724 First_Choice => First_Choice);
725 Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice);
727 Expect (Tok_Arrow, "`=>`");
728 Set_End_Of_Line (Current_Item);
729 Set_Previous_Line_Node (Current_Item);
731 Parse_Declarative_Items
733 Declarations => First_Declarative_Item,
734 In_Zone => In_Case_Construction,
735 First_Attribute => First_Attribute,
736 Current_Project => Current_Project,
737 Current_Package => Current_Package,
738 Packages_To_Check => Packages_To_Check);
740 Set_First_Declarative_Item_Of
741 (Current_Item, In_Tree, To => First_Declarative_Item);
746 End_Case_Construction
747 (Check_All_Labels => not When_Others and not Quiet_Output,
748 Case_Location => Location_Of (Case_Construction, In_Tree));
750 Expect (Tok_End, "`END CASE`");
751 Remove_Next_End_Node;
753 if Token = Tok_End then
759 Expect (Tok_Case, "CASE");
767 Expect (Tok_Semicolon, "`;`");
768 Set_Previous_End_Node (Case_Construction);
770 end Parse_Case_Construction;
772 -----------------------------
773 -- Parse_Declarative_Items --
774 -----------------------------
776 procedure Parse_Declarative_Items
777 (In_Tree : Project_Node_Tree_Ref;
778 Declarations : out Project_Node_Id;
780 First_Attribute : Attribute_Node_Id;
781 Current_Project : Project_Node_Id;
782 Current_Package : Project_Node_Id;
783 Packages_To_Check : String_List_Access)
785 Current_Declarative_Item : Project_Node_Id := Empty_Node;
786 Next_Declarative_Item : Project_Node_Id := Empty_Node;
787 Current_Declaration : Project_Node_Id := Empty_Node;
788 Item_Location : Source_Ptr := No_Location;
791 Declarations := Empty_Node;
794 -- We are always positioned at the token that precedes
795 -- the first token of the declarative element.
800 Item_Location := Token_Ptr;
803 when Tok_Identifier =>
805 if In_Zone = In_Case_Construction then
806 Error_Msg ("a variable cannot be declared here",
810 Parse_Variable_Declaration
813 Current_Project => Current_Project,
814 Current_Package => Current_Package);
816 Set_End_Of_Line (Current_Declaration);
817 Set_Previous_Line_Node (Current_Declaration);
821 Parse_Attribute_Declaration
823 Attribute => Current_Declaration,
824 First_Attribute => First_Attribute,
825 Current_Project => Current_Project,
826 Current_Package => Current_Package,
827 Packages_To_Check => Packages_To_Check);
829 Set_End_Of_Line (Current_Declaration);
830 Set_Previous_Line_Node (Current_Declaration);
834 Scan (In_Tree); -- past "null"
838 -- Package declaration
840 if In_Zone /= In_Project then
841 Error_Msg ("a package cannot be declared here", Token_Ptr);
844 Parse_Package_Declaration
846 Package_Declaration => Current_Declaration,
847 Current_Project => Current_Project,
848 Packages_To_Check => Packages_To_Check);
850 Set_Previous_End_Node (Current_Declaration);
854 -- Type String Declaration
856 if In_Zone /= In_Project then
857 Error_Msg ("a string type cannot be declared here",
861 Parse_String_Type_Declaration
863 String_Type => Current_Declaration,
864 Current_Project => Current_Project);
866 Set_End_Of_Line (Current_Declaration);
867 Set_Previous_Line_Node (Current_Declaration);
873 Parse_Case_Construction
875 Case_Construction => Current_Declaration,
876 First_Attribute => First_Attribute,
877 Current_Project => Current_Project,
878 Current_Package => Current_Package,
879 Packages_To_Check => Packages_To_Check);
881 Set_Previous_End_Node (Current_Declaration);
886 -- We are leaving Parse_Declarative_Items positionned
887 -- at the first token after the list of declarative items.
888 -- It could be "end" (for a project, a package declaration or
889 -- a case construction) or "when" (for a case construction)
893 Expect (Tok_Semicolon, "`;` after declarative items");
895 -- Insert an N_Declarative_Item in the tree, but only if
896 -- Current_Declaration is not an empty node.
898 if Current_Declaration /= Empty_Node then
899 if Current_Declarative_Item = Empty_Node then
900 Current_Declarative_Item :=
902 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
903 Declarations := Current_Declarative_Item;
906 Next_Declarative_Item :=
908 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
909 Set_Next_Declarative_Item
910 (Current_Declarative_Item, In_Tree,
911 To => Next_Declarative_Item);
912 Current_Declarative_Item := Next_Declarative_Item;
915 Set_Current_Item_Node
916 (Current_Declarative_Item, In_Tree,
917 To => Current_Declaration);
919 (Current_Declarative_Item, In_Tree, To => Item_Location);
922 end Parse_Declarative_Items;
924 -------------------------------
925 -- Parse_Package_Declaration --
926 -------------------------------
928 procedure Parse_Package_Declaration
929 (In_Tree : Project_Node_Tree_Ref;
930 Package_Declaration : out Project_Node_Id;
931 Current_Project : Project_Node_Id;
932 Packages_To_Check : String_List_Access)
934 First_Attribute : Attribute_Node_Id := Empty_Attribute;
935 Current_Package : Package_Node_Id := Empty_Package;
936 First_Declarative_Item : Project_Node_Id := Empty_Node;
938 Package_Location : constant Source_Ptr := Token_Ptr;
941 Package_Declaration :=
943 (Of_Kind => N_Package_Declaration, In_Tree => In_Tree);
944 Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location);
946 -- Scan past "package"
949 Expect (Tok_Identifier, "identifier");
951 if Token = Tok_Identifier then
952 Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name);
954 Current_Package := Package_Node_Id_Of (Token_Name);
956 if Current_Package /= Empty_Package then
957 First_Attribute := First_Attribute_Of (Current_Package);
960 if not Quiet_Output then
963 (Name_Of (Package_Declaration, In_Tree)) &
964 """ is not a known package name",
968 -- Set the package declaration to "ignored" so that it is not
969 -- processed by Prj.Proc.Process.
971 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
973 -- Add the unknown package in the list of packages
975 Add_Unknown_Package (Token_Name, Current_Package);
979 (Package_Declaration, In_Tree, To => Current_Package);
982 Current : Project_Node_Id :=
983 First_Package_Of (Current_Project, In_Tree);
986 while Current /= Empty_Node
987 and then Name_Of (Current, In_Tree) /= Token_Name
989 Current := Next_Package_In_Project (Current, In_Tree);
992 if Current /= Empty_Node then
995 Get_Name_String (Name_Of (Package_Declaration, In_Tree)) &
996 """ is declared twice in the same project",
1000 -- Add the package to the project list
1002 Set_Next_Package_In_Project
1003 (Package_Declaration, In_Tree,
1004 To => First_Package_Of (Current_Project, In_Tree));
1005 Set_First_Package_Of
1006 (Current_Project, In_Tree, To => Package_Declaration);
1010 -- Scan past the package name
1015 if Token = Tok_Renames then
1016 if In_Configuration then
1018 ("no package renames in configuration projects", Token_Ptr);
1021 -- Scan past "renames"
1025 Expect (Tok_Identifier, "identifier");
1027 if Token = Tok_Identifier then
1029 Project_Name : constant Name_Id := Token_Name;
1031 Clause : Project_Node_Id :=
1032 First_With_Clause_Of (Current_Project, In_Tree);
1033 The_Project : Project_Node_Id := Empty_Node;
1034 Extended : constant Project_Node_Id :=
1036 (Project_Declaration_Of
1037 (Current_Project, In_Tree),
1040 while Clause /= Empty_Node loop
1041 -- Only non limited imported projects may be used in a
1042 -- renames declaration.
1045 Non_Limited_Project_Node_Of (Clause, In_Tree);
1046 exit when The_Project /= Empty_Node
1047 and then Name_Of (The_Project, In_Tree) = Project_Name;
1048 Clause := Next_With_Clause_Of (Clause, In_Tree);
1051 if Clause = Empty_Node then
1052 -- As we have not found the project in the imports, we check
1053 -- if it's the name of an eventual extended project.
1055 if Extended /= Empty_Node
1056 and then Name_Of (Extended, In_Tree) = Project_Name
1058 Set_Project_Of_Renamed_Package_Of
1059 (Package_Declaration, In_Tree, To => Extended);
1061 Error_Msg_Name_1 := Project_Name;
1063 ("% is not an imported or extended project", Token_Ptr);
1066 Set_Project_Of_Renamed_Package_Of
1067 (Package_Declaration, In_Tree, To => The_Project);
1072 Expect (Tok_Dot, "`.`");
1074 if Token = Tok_Dot then
1076 Expect (Tok_Identifier, "identifier");
1078 if Token = Tok_Identifier then
1079 if Name_Of (Package_Declaration, In_Tree) /= Token_Name then
1080 Error_Msg ("not the same package name", Token_Ptr);
1082 Project_Of_Renamed_Package_Of
1083 (Package_Declaration, In_Tree) /= Empty_Node
1086 Current : Project_Node_Id :=
1088 (Project_Of_Renamed_Package_Of
1089 (Package_Declaration, In_Tree),
1093 while Current /= Empty_Node
1094 and then Name_Of (Current, In_Tree) /= Token_Name
1097 Next_Package_In_Project (Current, In_Tree);
1100 if Current = Empty_Node then
1103 Get_Name_String (Token_Name) &
1104 """ is not a package declared by the project",
1115 Expect (Tok_Semicolon, "`;`");
1116 Set_End_Of_Line (Package_Declaration);
1117 Set_Previous_Line_Node (Package_Declaration);
1119 elsif Token = Tok_Is then
1120 Set_End_Of_Line (Package_Declaration);
1121 Set_Previous_Line_Node (Package_Declaration);
1122 Set_Next_End_Node (Package_Declaration);
1124 Parse_Declarative_Items
1125 (In_Tree => In_Tree,
1126 Declarations => First_Declarative_Item,
1127 In_Zone => In_Package,
1128 First_Attribute => First_Attribute,
1129 Current_Project => Current_Project,
1130 Current_Package => Package_Declaration,
1131 Packages_To_Check => Packages_To_Check);
1133 Set_First_Declarative_Item_Of
1134 (Package_Declaration, In_Tree, To => First_Declarative_Item);
1136 Expect (Tok_End, "END");
1138 if Token = Tok_End then
1145 -- We should have the name of the package after "end"
1147 Expect (Tok_Identifier, "identifier");
1149 if Token = Tok_Identifier
1150 and then Name_Of (Package_Declaration, In_Tree) /= No_Name
1151 and then Token_Name /= Name_Of (Package_Declaration, In_Tree)
1153 Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree);
1154 Error_Msg ("expected %%", Token_Ptr);
1157 if Token /= Tok_Semicolon then
1159 -- Scan past the package name
1164 Expect (Tok_Semicolon, "`;`");
1165 Remove_Next_End_Node;
1168 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1171 end Parse_Package_Declaration;
1173 -----------------------------------
1174 -- Parse_String_Type_Declaration --
1175 -----------------------------------
1177 procedure Parse_String_Type_Declaration
1178 (In_Tree : Project_Node_Tree_Ref;
1179 String_Type : out Project_Node_Id;
1180 Current_Project : Project_Node_Id)
1182 Current : Project_Node_Id := Empty_Node;
1183 First_String : Project_Node_Id := Empty_Node;
1187 Default_Project_Node
1188 (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree);
1190 Set_Location_Of (String_Type, In_Tree, To => Token_Ptr);
1196 Expect (Tok_Identifier, "identifier");
1198 if Token = Tok_Identifier then
1199 Set_Name_Of (String_Type, In_Tree, To => Token_Name);
1201 Current := First_String_Type_Of (Current_Project, In_Tree);
1202 while Current /= Empty_Node
1204 Name_Of (Current, In_Tree) /= Token_Name
1206 Current := Next_String_Type (Current, In_Tree);
1209 if Current /= Empty_Node then
1210 Error_Msg ("duplicate string type name """ &
1211 Get_Name_String (Token_Name) &
1215 Current := First_Variable_Of (Current_Project, In_Tree);
1216 while Current /= Empty_Node
1217 and then Name_Of (Current, In_Tree) /= Token_Name
1219 Current := Next_Variable (Current, In_Tree);
1222 if Current /= Empty_Node then
1224 Get_Name_String (Token_Name) &
1225 """ is already a variable name", Token_Ptr);
1227 Set_Next_String_Type
1228 (String_Type, In_Tree,
1229 To => First_String_Type_Of (Current_Project, In_Tree));
1230 Set_First_String_Type_Of
1231 (Current_Project, In_Tree, To => String_Type);
1235 -- Scan past the name
1240 Expect (Tok_Is, "IS");
1242 if Token = Tok_Is then
1246 Expect (Tok_Left_Paren, "`(`");
1248 if Token = Tok_Left_Paren then
1252 Parse_String_Type_List
1253 (In_Tree => In_Tree, First_String => First_String);
1254 Set_First_Literal_String (String_Type, In_Tree, To => First_String);
1256 Expect (Tok_Right_Paren, "`)`");
1258 if Token = Tok_Right_Paren then
1262 end Parse_String_Type_Declaration;
1264 --------------------------------
1265 -- Parse_Variable_Declaration --
1266 --------------------------------
1268 procedure Parse_Variable_Declaration
1269 (In_Tree : Project_Node_Tree_Ref;
1270 Variable : out Project_Node_Id;
1271 Current_Project : Project_Node_Id;
1272 Current_Package : Project_Node_Id)
1274 Expression_Location : Source_Ptr;
1275 String_Type_Name : Name_Id := No_Name;
1276 Project_String_Type_Name : Name_Id := No_Name;
1277 Type_Location : Source_Ptr := No_Location;
1278 Project_Location : Source_Ptr := No_Location;
1279 Expression : Project_Node_Id := Empty_Node;
1280 Variable_Name : constant Name_Id := Token_Name;
1281 OK : Boolean := True;
1285 Default_Project_Node
1286 (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree);
1287 Set_Name_Of (Variable, In_Tree, To => Variable_Name);
1288 Set_Location_Of (Variable, In_Tree, To => Token_Ptr);
1290 -- Scan past the variable name
1294 if Token = Tok_Colon then
1296 -- Typed string variable declaration
1299 Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration);
1300 Expect (Tok_Identifier, "identifier");
1302 OK := Token = Tok_Identifier;
1305 String_Type_Name := Token_Name;
1306 Type_Location := Token_Ptr;
1309 if Token = Tok_Dot then
1310 Project_String_Type_Name := String_Type_Name;
1311 Project_Location := Type_Location;
1313 -- Scan past the dot
1316 Expect (Tok_Identifier, "identifier");
1318 if Token = Tok_Identifier then
1319 String_Type_Name := Token_Name;
1320 Type_Location := Token_Ptr;
1329 Current : Project_Node_Id :=
1330 First_String_Type_Of (Current_Project, In_Tree);
1333 if Project_String_Type_Name /= No_Name then
1335 The_Project_Name_And_Node : constant
1336 Tree_Private_Part.Project_Name_And_Node :=
1337 Tree_Private_Part.Projects_Htable.Get
1338 (In_Tree.Projects_HT, Project_String_Type_Name);
1340 use Tree_Private_Part;
1343 if The_Project_Name_And_Node =
1344 Tree_Private_Part.No_Project_Name_And_Node
1346 Error_Msg ("unknown project """ &
1348 (Project_String_Type_Name) &
1351 Current := Empty_Node;
1354 First_String_Type_Of
1355 (The_Project_Name_And_Node.Node, In_Tree);
1360 while Current /= Empty_Node
1361 and then Name_Of (Current, In_Tree) /= String_Type_Name
1363 Current := Next_String_Type (Current, In_Tree);
1366 if Current = Empty_Node then
1367 Error_Msg ("unknown string type """ &
1368 Get_Name_String (String_Type_Name) &
1374 (Variable, In_Tree, To => Current);
1381 Expect (Tok_Colon_Equal, "`:=`");
1383 OK := OK and (Token = Tok_Colon_Equal);
1385 if Token = Tok_Colon_Equal then
1389 -- Get the single string or string list value
1391 Expression_Location := Token_Ptr;
1394 (In_Tree => In_Tree,
1395 Expression => Expression,
1396 Current_Project => Current_Project,
1397 Current_Package => Current_Package,
1398 Optional_Index => False);
1399 Set_Expression_Of (Variable, In_Tree, To => Expression);
1401 if Expression /= Empty_Node then
1402 -- A typed string must have a single string value, not a list
1404 if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration
1405 and then Expression_Kind_Of (Expression, In_Tree) = List
1408 ("expression must be a single string", Expression_Location);
1411 Set_Expression_Kind_Of
1413 To => Expression_Kind_Of (Expression, In_Tree));
1418 The_Variable : Project_Node_Id := Empty_Node;
1421 if Current_Package /= Empty_Node then
1422 The_Variable := First_Variable_Of (Current_Package, In_Tree);
1423 elsif Current_Project /= Empty_Node then
1424 The_Variable := First_Variable_Of (Current_Project, In_Tree);
1427 while The_Variable /= Empty_Node
1428 and then Name_Of (The_Variable, In_Tree) /= Variable_Name
1430 The_Variable := Next_Variable (The_Variable, In_Tree);
1433 if The_Variable = Empty_Node then
1434 if Current_Package /= Empty_Node then
1437 To => First_Variable_Of (Current_Package, In_Tree));
1438 Set_First_Variable_Of
1439 (Current_Package, In_Tree, To => Variable);
1441 elsif Current_Project /= Empty_Node then
1444 To => First_Variable_Of (Current_Project, In_Tree));
1445 Set_First_Variable_Of
1446 (Current_Project, In_Tree, To => Variable);
1450 if Expression_Kind_Of (Variable, In_Tree) /= Undefined then
1452 Expression_Kind_Of (The_Variable, In_Tree) = Undefined
1454 Set_Expression_Kind_Of
1455 (The_Variable, In_Tree,
1456 To => Expression_Kind_Of (Variable, In_Tree));
1459 if Expression_Kind_Of (The_Variable, In_Tree) /=
1460 Expression_Kind_Of (Variable, In_Tree)
1462 Error_Msg ("wrong expression kind for variable """ &
1464 (Name_Of (The_Variable, In_Tree)) &
1466 Expression_Location);
1474 end Parse_Variable_Declaration;