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