1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2004 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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, 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;
28 with Namet; use Namet;
30 with Prj.Err; use Prj.Err;
31 with Prj.Strt; use Prj.Strt;
32 with Prj.Tree; use Prj.Tree;
33 with Scans; use Scans;
35 with Types; use Types;
36 with Prj.Attr; use Prj.Attr;
37 with Uintp; use Uintp;
39 package body Prj.Dect is
41 type Zone is (In_Project, In_Package, In_Case_Construction);
42 -- Used to indicate if we are parsing a package (In_Package),
43 -- a case construction (In_Case_Construction) or none of those two
46 procedure Parse_Attribute_Declaration
47 (Attribute : out Project_Node_Id;
48 First_Attribute : Attribute_Node_Id;
49 Current_Project : Project_Node_Id;
50 Current_Package : Project_Node_Id);
51 -- Parse an attribute declaration.
53 procedure Parse_Case_Construction
54 (Case_Construction : out Project_Node_Id;
55 First_Attribute : Attribute_Node_Id;
56 Current_Project : Project_Node_Id;
57 Current_Package : Project_Node_Id);
58 -- Parse a case construction
60 procedure Parse_Declarative_Items
61 (Declarations : out Project_Node_Id;
63 First_Attribute : Attribute_Node_Id;
64 Current_Project : Project_Node_Id;
65 Current_Package : Project_Node_Id);
66 -- Parse declarative items. Depending on In_Zone, some declarative
67 -- items may be forbiden.
69 procedure Parse_Package_Declaration
70 (Package_Declaration : out Project_Node_Id;
71 Current_Project : Project_Node_Id);
72 -- Parse a package declaration
74 procedure Parse_String_Type_Declaration
75 (String_Type : out Project_Node_Id;
76 Current_Project : Project_Node_Id);
77 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
79 procedure Parse_Variable_Declaration
80 (Variable : out Project_Node_Id;
81 Current_Project : Project_Node_Id;
82 Current_Package : Project_Node_Id);
83 -- Parse a variable assignment
84 -- <variable_Name> := <expression>; OR
85 -- <variable_Name> : <string_type_Name> := <string_expression>;
92 (Declarations : out Project_Node_Id;
93 Current_Project : Project_Node_Id;
94 Extends : Project_Node_Id)
96 First_Declarative_Item : Project_Node_Id := Empty_Node;
99 Declarations := Default_Project_Node (Of_Kind => N_Project_Declaration);
100 Set_Location_Of (Declarations, To => Token_Ptr);
101 Set_Extended_Project_Of (Declarations, To => Extends);
102 Set_Project_Declaration_Of (Current_Project, Declarations);
103 Parse_Declarative_Items
104 (Declarations => First_Declarative_Item,
105 In_Zone => In_Project,
106 First_Attribute => Prj.Attr.Attribute_First,
107 Current_Project => Current_Project,
108 Current_Package => Empty_Node);
109 Set_First_Declarative_Item_Of
110 (Declarations, To => First_Declarative_Item);
113 ---------------------------------
114 -- Parse_Attribute_Declaration --
115 ---------------------------------
117 procedure Parse_Attribute_Declaration
118 (Attribute : out Project_Node_Id;
119 First_Attribute : Attribute_Node_Id;
120 Current_Project : Project_Node_Id;
121 Current_Package : Project_Node_Id)
123 Current_Attribute : Attribute_Node_Id := First_Attribute;
124 Full_Associative_Array : Boolean := False;
125 Attribute_Name : Name_Id := No_Name;
126 Optional_Index : Boolean := False;
129 Attribute := Default_Project_Node (Of_Kind => N_Attribute_Declaration);
130 Set_Location_Of (Attribute, To => Token_Ptr);
131 Set_Previous_Line_Node (Attribute);
137 -- Body may be an attribute name
139 if Token = Tok_Body then
140 Token := Tok_Identifier;
141 Token_Name := Snames.Name_Body;
144 Expect (Tok_Identifier, "identifier");
146 if Token = Tok_Identifier then
147 Attribute_Name := Token_Name;
148 Set_Name_Of (Attribute, To => Token_Name);
149 Set_Location_Of (Attribute, To => Token_Ptr);
151 -- Find the attribute
153 while Current_Attribute /= Empty_Attribute
155 Attributes.Table (Current_Attribute).Name /= Token_Name
157 Current_Attribute := Attributes.Table (Current_Attribute).Next;
160 -- If not a valid attribute name, issue an error, or a warning
161 -- if inside a package that does not need to be checked.
163 if Current_Attribute = Empty_Attribute then
165 Message : constant String :=
166 "undefined attribute """ &
167 Get_Name_String (Name_Of (Attribute)) & '"';
170 Current_Package /= Empty_Node
171 and then Current_Packages_To_Check /= All_Packages;
176 -- Check that we are not in a package to check
178 Get_Name_String (Name_Of (Current_Package));
180 for Index in Current_Packages_To_Check'Range loop
181 if Name_Buffer (1 .. Name_Len) =
182 Current_Packages_To_Check (Index).all
191 Error_Msg ('?' & Message, Token_Ptr);
194 Error_Msg (Message, Token_Ptr);
198 -- Set, if appropriate the index case insensitivity flag
200 elsif Attributes.Table (Current_Attribute).Kind_2 in
201 Case_Insensitive_Associative_Array ..
202 Optional_Index_Case_Insensitive_Associative_Array
204 Set_Case_Insensitive (Attribute, To => True);
207 Scan; -- past the attribute name
210 -- Change obsolete names of attributes to the new names
212 case Name_Of (Attribute) is
213 when Snames.Name_Specification =>
214 Set_Name_Of (Attribute, To => Snames.Name_Spec);
216 when Snames.Name_Specification_Suffix =>
217 Set_Name_Of (Attribute, To => Snames.Name_Spec_Suffix);
219 when Snames.Name_Implementation =>
220 Set_Name_Of (Attribute, To => Snames.Name_Body);
222 when Snames.Name_Implementation_Suffix =>
223 Set_Name_Of (Attribute, To => Snames.Name_Body_Suffix);
229 -- Associative array attributes
231 if Token = Tok_Left_Paren then
233 -- If the attribute is not an associative array attribute, report
236 if Current_Attribute /= Empty_Attribute
237 and then Attributes.Table (Current_Attribute).Kind_2 = Single
239 Error_Msg ("the attribute """ &
241 (Attributes.Table (Current_Attribute).Name) &
242 """ cannot be an associative array",
243 Location_Of (Attribute));
246 Scan; -- past the left parenthesis
247 Expect (Tok_String_Literal, "literal string");
249 if Token = Tok_String_Literal then
250 Set_Associative_Array_Index_Of (Attribute, Token_Name);
251 Scan; -- past the literal string index
253 if Token = Tok_At then
254 case Attributes.Table (Current_Attribute).Kind_2 is
255 when Optional_Index_Associative_Array |
256 Optional_Index_Case_Insensitive_Associative_Array =>
258 Expect (Tok_Integer_Literal, "integer literal");
260 if Token = Tok_Integer_Literal then
262 -- Set the source index value from given literal
265 Index : constant Int :=
266 UI_To_Int (Int_Literal_Value);
269 Error_Msg ("index cannot be zero", Token_Ptr);
271 Set_Source_Index_Of (Attribute, To => Index);
279 Error_Msg ("index not allowed here", Token_Ptr);
282 if Token = Tok_Integer_Literal then
289 Expect (Tok_Right_Paren, "`)`");
291 if Token = Tok_Right_Paren then
292 Scan; -- past the right parenthesis
296 -- If it is an associative array attribute and there are no left
297 -- parenthesis, then this is a full associative array declaration.
298 -- Flag it as such for later processing of its value.
300 if Current_Attribute /= Empty_Attribute
302 Attributes.Table (Current_Attribute).Kind_2 /= Single
304 Full_Associative_Array := True;
308 -- Set the expression kind of the attribute
310 if Current_Attribute /= Empty_Attribute then
311 Set_Expression_Kind_Of
312 (Attribute, To => Attributes.Table (Current_Attribute).Kind_1);
313 Optional_Index := Attributes.Table (Current_Attribute).Optional_Index;
316 Expect (Tok_Use, "USE");
318 if Token = Tok_Use then
321 if Full_Associative_Array then
323 -- Expect <project>'<same_attribute_name>, or
324 -- <project>.<same_package_name>'<same_attribute_name>
327 The_Project : Project_Node_Id := Empty_Node;
328 -- The node of the project where the associative array is
331 The_Package : Project_Node_Id := Empty_Node;
332 -- The node of the package where the associative array is
335 Project_Name : Name_Id := No_Name;
336 -- The name of the project where the associative array is
339 Location : Source_Ptr := No_Location;
340 -- The location of the project name
343 Expect (Tok_Identifier, "identifier");
345 if Token = Tok_Identifier then
346 Location := Token_Ptr;
348 -- Find the project node in the imported project or
349 -- in the project being extended.
351 The_Project := Imported_Or_Extended_Project_Of
352 (Current_Project, Token_Name);
354 if The_Project = Empty_Node then
355 Error_Msg ("unknown project", Location);
356 Scan; -- past the project name
359 Project_Name := Token_Name;
360 Scan; -- past the project name
362 -- If this is inside a package, a dot followed by the
363 -- name of the package must followed the project name.
365 if Current_Package /= Empty_Node then
366 Expect (Tok_Dot, "`.`");
368 if Token /= Tok_Dot then
369 The_Project := Empty_Node;
372 Scan; -- past the dot
373 Expect (Tok_Identifier, "identifier");
375 if Token /= Tok_Identifier then
376 The_Project := Empty_Node;
378 -- If it is not the same package name, issue error
380 elsif Token_Name /= Name_Of (Current_Package) then
381 The_Project := Empty_Node;
383 ("not the same package as " &
384 Get_Name_String (Name_Of (Current_Package)),
388 The_Package := First_Package_Of (The_Project);
390 -- Look for the package node
392 while The_Package /= Empty_Node
393 and then Name_Of (The_Package) /= Token_Name
396 Next_Package_In_Project (The_Package);
399 -- If the package cannot be found in the
400 -- project, issue an error.
402 if The_Package = Empty_Node then
403 The_Project := Empty_Node;
404 Error_Msg_Name_2 := Project_Name;
405 Error_Msg_Name_1 := Token_Name;
407 ("package % not declared in project %",
411 Scan; -- past the package name
418 if The_Project /= Empty_Node then
420 -- Looking for '<same attribute name>
422 Expect (Tok_Apostrophe, "`''`");
424 if Token /= Tok_Apostrophe then
425 The_Project := Empty_Node;
428 Scan; -- past the apostrophe
429 Expect (Tok_Identifier, "identifier");
431 if Token /= Tok_Identifier then
432 The_Project := Empty_Node;
435 -- If it is not the same attribute name, issue error
437 if Token_Name /= Attribute_Name then
438 The_Project := Empty_Node;
439 Error_Msg_Name_1 := Attribute_Name;
440 Error_Msg ("invalid name, should be %", Token_Ptr);
443 Scan; -- past the attribute name
448 if The_Project = Empty_Node then
450 -- If there were any problem, set the attribute id to null,
451 -- so that the node will not be recorded.
453 Current_Attribute := Empty_Attribute;
456 -- Set the appropriate field in the node.
457 -- Note that the index and the expression are nil. This
458 -- characterizes full associative array attribute
461 Set_Associative_Project_Of (Attribute, The_Project);
462 Set_Associative_Package_Of (Attribute, The_Package);
466 -- Other attribute declarations (not full associative array)
470 Expression_Location : constant Source_Ptr := Token_Ptr;
471 -- The location of the first token of the expression
473 Expression : Project_Node_Id := Empty_Node;
474 -- The expression, value for the attribute declaration
477 -- Get the expression value and set it in the attribute node
480 (Expression => Expression,
481 Current_Project => Current_Project,
482 Current_Package => Current_Package,
483 Optional_Index => Optional_Index);
484 Set_Expression_Of (Attribute, To => Expression);
486 -- If the expression is legal, but not of the right kind
487 -- for the attribute, issue an error.
489 if Current_Attribute /= Empty_Attribute
490 and then Expression /= Empty_Node
491 and then Attributes.Table (Current_Attribute).Kind_1 /=
492 Expression_Kind_Of (Expression)
495 ("wrong expression kind for attribute """ &
497 (Attributes.Table (Current_Attribute).Name) &
499 Expression_Location);
505 -- If the attribute was not recognized, return an empty node.
506 -- It may be that it is not in a package to check, and the node will
507 -- not be added to the tree.
509 if Current_Attribute = Empty_Attribute then
510 Attribute := Empty_Node;
513 Set_End_Of_Line (Attribute);
514 Set_Previous_Line_Node (Attribute);
515 end Parse_Attribute_Declaration;
517 -----------------------------
518 -- Parse_Case_Construction --
519 -----------------------------
521 procedure Parse_Case_Construction
522 (Case_Construction : out Project_Node_Id;
523 First_Attribute : Attribute_Node_Id;
524 Current_Project : Project_Node_Id;
525 Current_Package : Project_Node_Id)
527 Current_Item : Project_Node_Id := Empty_Node;
528 Next_Item : Project_Node_Id := Empty_Node;
529 First_Case_Item : Boolean := True;
531 Variable_Location : Source_Ptr := No_Location;
533 String_Type : Project_Node_Id := Empty_Node;
535 Case_Variable : Project_Node_Id := Empty_Node;
537 First_Declarative_Item : Project_Node_Id := Empty_Node;
539 First_Choice : Project_Node_Id := Empty_Node;
541 When_Others : Boolean := False;
542 -- Set to True when there is a "when others =>" clause
546 Default_Project_Node (Of_Kind => N_Case_Construction);
547 Set_Location_Of (Case_Construction, To => Token_Ptr);
553 -- Get the switch variable
555 Expect (Tok_Identifier, "identifier");
557 if Token = Tok_Identifier then
558 Variable_Location := Token_Ptr;
559 Parse_Variable_Reference
560 (Variable => Case_Variable,
561 Current_Project => Current_Project,
562 Current_Package => Current_Package);
563 Set_Case_Variable_Reference_Of
564 (Case_Construction, To => Case_Variable);
567 if Token /= Tok_Is then
572 if Case_Variable /= Empty_Node then
573 String_Type := String_Type_Of (Case_Variable);
575 if String_Type = Empty_Node then
576 Error_Msg ("variable """ &
577 Get_Name_String (Name_Of (Case_Variable)) &
583 Expect (Tok_Is, "IS");
585 if Token = Tok_Is then
586 Set_End_Of_Line (Case_Construction);
587 Set_Previous_Line_Node (Case_Construction);
588 Set_Next_End_Node (Case_Construction);
595 Start_New_Case_Construction (String_Type);
599 while Token = Tok_When loop
601 if First_Case_Item then
602 Current_Item := Default_Project_Node (Of_Kind => N_Case_Item);
603 Set_First_Case_Item_Of (Case_Construction, To => Current_Item);
604 First_Case_Item := False;
607 Next_Item := Default_Project_Node (Of_Kind => N_Case_Item);
608 Set_Next_Case_Item (Current_Item, To => Next_Item);
609 Current_Item := Next_Item;
612 Set_Location_Of (Current_Item, To => Token_Ptr);
618 if Token = Tok_Others then
621 -- Scan past "others"
625 Expect (Tok_Arrow, "`=>`");
626 Set_End_Of_Line (Current_Item);
627 Set_Previous_Line_Node (Current_Item);
629 -- Empty_Node in Field1 of a Case_Item indicates
630 -- the "when others =>" branch.
632 Set_First_Choice_Of (Current_Item, To => Empty_Node);
634 Parse_Declarative_Items
635 (Declarations => First_Declarative_Item,
636 In_Zone => In_Case_Construction,
637 First_Attribute => First_Attribute,
638 Current_Project => Current_Project,
639 Current_Package => Current_Package);
641 -- "when others =>" must be the last branch, so save the
642 -- Case_Item and exit
644 Set_First_Declarative_Item_Of
645 (Current_Item, To => First_Declarative_Item);
649 Parse_Choice_List (First_Choice => First_Choice);
650 Set_First_Choice_Of (Current_Item, To => First_Choice);
652 Expect (Tok_Arrow, "`=>`");
653 Set_End_Of_Line (Current_Item);
654 Set_Previous_Line_Node (Current_Item);
656 Parse_Declarative_Items
657 (Declarations => First_Declarative_Item,
658 In_Zone => In_Case_Construction,
659 First_Attribute => First_Attribute,
660 Current_Project => Current_Project,
661 Current_Package => Current_Package);
663 Set_First_Declarative_Item_Of
664 (Current_Item, To => First_Declarative_Item);
669 End_Case_Construction
670 (Check_All_Labels => not When_Others and not Quiet_Output,
671 Case_Location => Location_Of (Case_Construction));
673 Expect (Tok_End, "`END CASE`");
674 Remove_Next_End_Node;
676 if Token = Tok_End then
682 Expect (Tok_Case, "CASE");
690 Expect (Tok_Semicolon, "`;`");
691 Set_Previous_End_Node (Case_Construction);
693 end Parse_Case_Construction;
695 -----------------------------
696 -- Parse_Declarative_Items --
697 -----------------------------
699 procedure Parse_Declarative_Items
700 (Declarations : out Project_Node_Id;
702 First_Attribute : Attribute_Node_Id;
703 Current_Project : Project_Node_Id;
704 Current_Package : Project_Node_Id)
706 Current_Declarative_Item : Project_Node_Id := Empty_Node;
707 Next_Declarative_Item : Project_Node_Id := Empty_Node;
708 Current_Declaration : Project_Node_Id := Empty_Node;
709 Item_Location : Source_Ptr := No_Location;
712 Declarations := Empty_Node;
715 -- We are always positioned at the token that precedes
716 -- the first token of the declarative element.
721 Item_Location := Token_Ptr;
724 when Tok_Identifier =>
726 if In_Zone = In_Case_Construction then
727 Error_Msg ("a variable cannot be declared here",
731 Parse_Variable_Declaration
732 (Current_Declaration,
733 Current_Project => Current_Project,
734 Current_Package => Current_Package);
736 Set_End_Of_Line (Current_Declaration);
737 Set_Previous_Line_Node (Current_Declaration);
741 Parse_Attribute_Declaration
742 (Attribute => Current_Declaration,
743 First_Attribute => First_Attribute,
744 Current_Project => Current_Project,
745 Current_Package => Current_Package);
747 Set_End_Of_Line (Current_Declaration);
748 Set_Previous_Line_Node (Current_Declaration);
756 -- Package declaration
758 if In_Zone /= In_Project then
759 Error_Msg ("a package cannot be declared here", Token_Ptr);
762 Parse_Package_Declaration
763 (Package_Declaration => Current_Declaration,
764 Current_Project => Current_Project);
766 Set_Previous_End_Node (Current_Declaration);
770 -- Type String Declaration
772 if In_Zone /= In_Project then
773 Error_Msg ("a string type cannot be declared here",
777 Parse_String_Type_Declaration
778 (String_Type => Current_Declaration,
779 Current_Project => Current_Project);
781 Set_End_Of_Line (Current_Declaration);
782 Set_Previous_Line_Node (Current_Declaration);
788 Parse_Case_Construction
789 (Case_Construction => Current_Declaration,
790 First_Attribute => First_Attribute,
791 Current_Project => Current_Project,
792 Current_Package => Current_Package);
794 Set_Previous_End_Node (Current_Declaration);
799 -- We are leaving Parse_Declarative_Items positionned
800 -- at the first token after the list of declarative items.
801 -- It could be "end" (for a project, a package declaration or
802 -- a case construction) or "when" (for a case construction)
806 Expect (Tok_Semicolon, "`;` after declarative items");
808 -- Insert an N_Declarative_Item in the tree, but only if
809 -- Current_Declaration is not an empty node.
811 if Current_Declaration /= Empty_Node then
812 if Current_Declarative_Item = Empty_Node then
813 Current_Declarative_Item :=
814 Default_Project_Node (Of_Kind => N_Declarative_Item);
815 Declarations := Current_Declarative_Item;
818 Next_Declarative_Item :=
819 Default_Project_Node (Of_Kind => N_Declarative_Item);
820 Set_Next_Declarative_Item
821 (Current_Declarative_Item, To => Next_Declarative_Item);
822 Current_Declarative_Item := Next_Declarative_Item;
825 Set_Current_Item_Node
826 (Current_Declarative_Item, To => Current_Declaration);
827 Set_Location_Of (Current_Declarative_Item, To => Item_Location);
832 end Parse_Declarative_Items;
834 -------------------------------
835 -- Parse_Package_Declaration --
836 -------------------------------
838 procedure Parse_Package_Declaration
839 (Package_Declaration : out Project_Node_Id;
840 Current_Project : Project_Node_Id)
842 First_Attribute : Attribute_Node_Id := Empty_Attribute;
843 Current_Package : Package_Node_Id := Empty_Package;
844 First_Declarative_Item : Project_Node_Id := Empty_Node;
847 Package_Declaration :=
848 Default_Project_Node (Of_Kind => N_Package_Declaration);
849 Set_Location_Of (Package_Declaration, To => Token_Ptr);
851 -- Scan past "package"
855 Expect (Tok_Identifier, "identifier");
857 if Token = Tok_Identifier then
859 Set_Name_Of (Package_Declaration, To => Token_Name);
861 for Index in Package_Attributes.First .. Package_Attributes.Last loop
862 if Token_Name = Package_Attributes.Table (Index).Name then
864 Package_Attributes.Table (Index).First_Attribute;
865 Current_Package := Index;
870 if Current_Package = Empty_Package then
872 Get_Name_String (Name_Of (Package_Declaration)) &
873 """ is not an allowed package name",
876 -- Set the package declaration to "ignored" so that it is not
877 -- processed by Prj.Proc.Process.
879 Set_Expression_Kind_Of (Package_Declaration, Ignored);
882 Set_Package_Id_Of (Package_Declaration, To => Current_Package);
885 Current : Project_Node_Id := First_Package_Of (Current_Project);
888 while Current /= Empty_Node
889 and then Name_Of (Current) /= Token_Name
891 Current := Next_Package_In_Project (Current);
894 if Current /= Empty_Node then
897 Get_Name_String (Name_Of (Package_Declaration)) &
898 """ is declared twice in the same project",
902 -- Add the package to the project list
904 Set_Next_Package_In_Project
905 (Package_Declaration,
906 To => First_Package_Of (Current_Project));
908 (Current_Project, To => Package_Declaration);
913 -- Scan past the package name
918 if Token = Tok_Renames then
920 -- Scan past "renames"
924 Expect (Tok_Identifier, "identifier");
926 if Token = Tok_Identifier then
928 Project_Name : constant Name_Id := Token_Name;
929 Clause : Project_Node_Id :=
930 First_With_Clause_Of (Current_Project);
931 The_Project : Project_Node_Id := Empty_Node;
932 Extended : constant Project_Node_Id :=
934 (Project_Declaration_Of (Current_Project));
936 while Clause /= Empty_Node loop
937 -- Only non limited imported projects may be used
938 -- in a renames declaration.
940 The_Project := Non_Limited_Project_Node_Of (Clause);
941 exit when The_Project /= Empty_Node
942 and then Name_Of (The_Project) = Project_Name;
943 Clause := Next_With_Clause_Of (Clause);
946 if Clause = Empty_Node then
947 -- As we have not found the project in the imports, we check
948 -- if it's the name of an eventual extended project.
950 if Extended /= Empty_Node
951 and then Name_Of (Extended) = Project_Name then
952 Set_Project_Of_Renamed_Package_Of
953 (Package_Declaration, To => Extended);
955 Error_Msg_Name_1 := Project_Name;
957 ("% is not an imported or extended project", Token_Ptr);
960 Set_Project_Of_Renamed_Package_Of
961 (Package_Declaration, To => The_Project);
966 Expect (Tok_Dot, "`.`");
968 if Token = Tok_Dot then
970 Expect (Tok_Identifier, "identifier");
972 if Token = Tok_Identifier then
973 if Name_Of (Package_Declaration) /= Token_Name then
974 Error_Msg ("not the same package name", Token_Ptr);
976 Project_Of_Renamed_Package_Of (Package_Declaration)
980 Current : Project_Node_Id :=
982 (Project_Of_Renamed_Package_Of
983 (Package_Declaration));
986 while Current /= Empty_Node
987 and then Name_Of (Current) /= Token_Name
989 Current := Next_Package_In_Project (Current);
992 if Current = Empty_Node then
995 Get_Name_String (Token_Name) &
996 """ is not a package declared by the project",
1007 Expect (Tok_Semicolon, "`;`");
1008 Set_End_Of_Line (Package_Declaration);
1009 Set_Previous_Line_Node (Package_Declaration);
1011 elsif Token = Tok_Is then
1012 Set_End_Of_Line (Package_Declaration);
1013 Set_Previous_Line_Node (Package_Declaration);
1014 Set_Next_End_Node (Package_Declaration);
1016 Parse_Declarative_Items
1017 (Declarations => First_Declarative_Item,
1018 In_Zone => In_Package,
1019 First_Attribute => First_Attribute,
1020 Current_Project => Current_Project,
1021 Current_Package => Package_Declaration);
1023 Set_First_Declarative_Item_Of
1024 (Package_Declaration, To => First_Declarative_Item);
1026 Expect (Tok_End, "END");
1028 if Token = Tok_End then
1035 -- We should have the name of the package after "end"
1037 Expect (Tok_Identifier, "identifier");
1039 if Token = Tok_Identifier
1040 and then Name_Of (Package_Declaration) /= No_Name
1041 and then Token_Name /= Name_Of (Package_Declaration)
1043 Error_Msg_Name_1 := Name_Of (Package_Declaration);
1044 Error_Msg ("expected {", Token_Ptr);
1047 if Token /= Tok_Semicolon then
1049 -- Scan past the package name
1054 Expect (Tok_Semicolon, "`;`");
1055 Remove_Next_End_Node;
1058 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1061 end Parse_Package_Declaration;
1063 -----------------------------------
1064 -- Parse_String_Type_Declaration --
1065 -----------------------------------
1067 procedure Parse_String_Type_Declaration
1068 (String_Type : out Project_Node_Id;
1069 Current_Project : Project_Node_Id)
1071 Current : Project_Node_Id := Empty_Node;
1072 First_String : Project_Node_Id := Empty_Node;
1076 Default_Project_Node (Of_Kind => N_String_Type_Declaration);
1078 Set_Location_Of (String_Type, To => Token_Ptr);
1084 Expect (Tok_Identifier, "identifier");
1086 if Token = Tok_Identifier then
1087 Set_Name_Of (String_Type, To => Token_Name);
1089 Current := First_String_Type_Of (Current_Project);
1090 while Current /= Empty_Node
1092 Name_Of (Current) /= Token_Name
1094 Current := Next_String_Type (Current);
1097 if Current /= Empty_Node then
1098 Error_Msg ("duplicate string type name """ &
1099 Get_Name_String (Token_Name) &
1103 Current := First_Variable_Of (Current_Project);
1104 while Current /= Empty_Node
1105 and then Name_Of (Current) /= Token_Name
1107 Current := Next_Variable (Current);
1110 if Current /= Empty_Node then
1112 Get_Name_String (Token_Name) &
1113 """ is already a variable name", Token_Ptr);
1115 Set_Next_String_Type
1116 (String_Type, To => First_String_Type_Of (Current_Project));
1117 Set_First_String_Type_Of (Current_Project, To => String_Type);
1121 -- Scan past the name
1126 Expect (Tok_Is, "IS");
1128 if Token = Tok_Is then
1132 Expect (Tok_Left_Paren, "`(`");
1134 if Token = Tok_Left_Paren then
1138 Parse_String_Type_List (First_String => First_String);
1139 Set_First_Literal_String (String_Type, To => First_String);
1141 Expect (Tok_Right_Paren, "`)`");
1143 if Token = Tok_Right_Paren then
1147 end Parse_String_Type_Declaration;
1149 --------------------------------
1150 -- Parse_Variable_Declaration --
1151 --------------------------------
1153 procedure Parse_Variable_Declaration
1154 (Variable : out Project_Node_Id;
1155 Current_Project : Project_Node_Id;
1156 Current_Package : Project_Node_Id)
1158 Expression_Location : Source_Ptr;
1159 String_Type_Name : Name_Id := No_Name;
1160 Project_String_Type_Name : Name_Id := No_Name;
1161 Type_Location : Source_Ptr := No_Location;
1162 Project_Location : Source_Ptr := No_Location;
1163 Expression : Project_Node_Id := Empty_Node;
1164 Variable_Name : constant Name_Id := Token_Name;
1165 OK : Boolean := True;
1169 Default_Project_Node (Of_Kind => N_Variable_Declaration);
1170 Set_Name_Of (Variable, To => Variable_Name);
1171 Set_Location_Of (Variable, To => Token_Ptr);
1173 -- Scan past the variable name
1177 if Token = Tok_Colon then
1179 -- Typed string variable declaration
1182 Set_Kind_Of (Variable, N_Typed_Variable_Declaration);
1183 Expect (Tok_Identifier, "identifier");
1185 OK := Token = Tok_Identifier;
1188 String_Type_Name := Token_Name;
1189 Type_Location := Token_Ptr;
1192 if Token = Tok_Dot then
1193 Project_String_Type_Name := String_Type_Name;
1194 Project_Location := Type_Location;
1196 -- Scan past the dot
1199 Expect (Tok_Identifier, "identifier");
1201 if Token = Tok_Identifier then
1202 String_Type_Name := Token_Name;
1203 Type_Location := Token_Ptr;
1212 Current : Project_Node_Id :=
1213 First_String_Type_Of (Current_Project);
1216 if Project_String_Type_Name /= No_Name then
1218 The_Project_Name_And_Node : constant
1219 Tree_Private_Part.Project_Name_And_Node :=
1220 Tree_Private_Part.Projects_Htable.Get
1221 (Project_String_Type_Name);
1223 use Tree_Private_Part;
1226 if The_Project_Name_And_Node =
1227 Tree_Private_Part.No_Project_Name_And_Node
1229 Error_Msg ("unknown project """ &
1231 (Project_String_Type_Name) &
1234 Current := Empty_Node;
1237 First_String_Type_Of
1238 (The_Project_Name_And_Node.Node);
1243 while Current /= Empty_Node
1244 and then Name_Of (Current) /= String_Type_Name
1246 Current := Next_String_Type (Current);
1249 if Current = Empty_Node then
1250 Error_Msg ("unknown string type """ &
1251 Get_Name_String (String_Type_Name) &
1257 (Variable, To => Current);
1264 Expect (Tok_Colon_Equal, "`:=`");
1266 OK := OK and (Token = Tok_Colon_Equal);
1268 if Token = Tok_Colon_Equal then
1272 -- Get the single string or string list value
1274 Expression_Location := Token_Ptr;
1277 (Expression => Expression,
1278 Current_Project => Current_Project,
1279 Current_Package => Current_Package,
1280 Optional_Index => False);
1281 Set_Expression_Of (Variable, To => Expression);
1283 if Expression /= Empty_Node then
1284 -- A typed string must have a single string value, not a list
1286 if Kind_Of (Variable) = N_Typed_Variable_Declaration
1287 and then Expression_Kind_Of (Expression) = List
1290 ("expression must be a single string", Expression_Location);
1293 Set_Expression_Kind_Of
1294 (Variable, To => Expression_Kind_Of (Expression));
1299 The_Variable : Project_Node_Id := Empty_Node;
1302 if Current_Package /= Empty_Node then
1303 The_Variable := First_Variable_Of (Current_Package);
1304 elsif Current_Project /= Empty_Node then
1305 The_Variable := First_Variable_Of (Current_Project);
1308 while The_Variable /= Empty_Node
1309 and then Name_Of (The_Variable) /= Variable_Name
1311 The_Variable := Next_Variable (The_Variable);
1314 if The_Variable = Empty_Node then
1315 if Current_Package /= Empty_Node then
1317 (Variable, To => First_Variable_Of (Current_Package));
1318 Set_First_Variable_Of (Current_Package, To => Variable);
1320 elsif Current_Project /= Empty_Node then
1322 (Variable, To => First_Variable_Of (Current_Project));
1323 Set_First_Variable_Of (Current_Project, To => Variable);
1327 if Expression_Kind_Of (Variable) /= Undefined then
1328 if Expression_Kind_Of (The_Variable) = Undefined then
1329 Set_Expression_Kind_Of
1330 (The_Variable, To => Expression_Kind_Of (Variable));
1333 if Expression_Kind_Of (The_Variable) /=
1334 Expression_Kind_Of (Variable)
1336 Error_Msg ("wrong expression kind for variable """ &
1337 Get_Name_String (Name_Of (The_Variable)) &
1339 Expression_Location);
1347 end Parse_Variable_Declaration;