1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2009, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Err_Vars
; use Err_Vars
;
28 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
29 with GNAT
.Spelling_Checker
; use GNAT
.Spelling_Checker
;
32 with Prj
.Attr
; use Prj
.Attr
;
33 with Prj
.Attr
.PM
; use Prj
.Attr
.PM
;
34 with Prj
.Err
; use Prj
.Err
;
35 with Prj
.Strt
; use Prj
.Strt
;
36 with Prj
.Tree
; use Prj
.Tree
;
38 with Uintp
; use Uintp
;
42 package body Prj
.Dect
is
46 type Zone
is (In_Project
, In_Package
, In_Case_Construction
);
47 -- Used to indicate if we are parsing a package (In_Package),
48 -- a case construction (In_Case_Construction) or none of those two
51 procedure Parse_Attribute_Declaration
52 (In_Tree
: Project_Node_Tree_Ref
;
53 Attribute
: out Project_Node_Id
;
54 First_Attribute
: Attribute_Node_Id
;
55 Current_Project
: Project_Node_Id
;
56 Current_Package
: Project_Node_Id
;
57 Packages_To_Check
: String_List_Access
;
58 Flags
: Processing_Flags
);
59 -- Parse an attribute declaration
61 procedure Parse_Case_Construction
62 (In_Tree
: Project_Node_Tree_Ref
;
63 Case_Construction
: out Project_Node_Id
;
64 First_Attribute
: Attribute_Node_Id
;
65 Current_Project
: Project_Node_Id
;
66 Current_Package
: Project_Node_Id
;
67 Packages_To_Check
: String_List_Access
;
68 Is_Config_File
: Boolean;
69 Flags
: Processing_Flags
);
70 -- Parse a case construction
72 procedure Parse_Declarative_Items
73 (In_Tree
: Project_Node_Tree_Ref
;
74 Declarations
: out Project_Node_Id
;
76 First_Attribute
: Attribute_Node_Id
;
77 Current_Project
: Project_Node_Id
;
78 Current_Package
: Project_Node_Id
;
79 Packages_To_Check
: String_List_Access
;
80 Is_Config_File
: Boolean;
81 Flags
: Processing_Flags
);
82 -- Parse declarative items. Depending on In_Zone, some declarative items
83 -- may be forbidden. Is_Config_File should be set to True if the project
84 -- represents a config file (.cgpr) since some specific checks apply.
86 procedure Parse_Package_Declaration
87 (In_Tree
: Project_Node_Tree_Ref
;
88 Package_Declaration
: out Project_Node_Id
;
89 Current_Project
: Project_Node_Id
;
90 Packages_To_Check
: String_List_Access
;
91 Is_Config_File
: Boolean;
92 Flags
: Processing_Flags
);
93 -- Parse a package declaration.
94 -- Is_Config_File should be set to True if the project represents a config
95 -- file (.cgpr) since some specific checks apply.
97 procedure Parse_String_Type_Declaration
98 (In_Tree
: Project_Node_Tree_Ref
;
99 String_Type
: out Project_Node_Id
;
100 Current_Project
: Project_Node_Id
;
101 Flags
: Processing_Flags
);
102 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
104 procedure Parse_Variable_Declaration
105 (In_Tree
: Project_Node_Tree_Ref
;
106 Variable
: out Project_Node_Id
;
107 Current_Project
: Project_Node_Id
;
108 Current_Package
: Project_Node_Id
;
109 Flags
: Processing_Flags
);
110 -- Parse a variable assignment
111 -- <variable_Name> := <expression>; OR
112 -- <variable_Name> : <string_type_Name> := <string_expression>;
119 (In_Tree
: Project_Node_Tree_Ref
;
120 Declarations
: out Project_Node_Id
;
121 Current_Project
: Project_Node_Id
;
122 Extends
: Project_Node_Id
;
123 Packages_To_Check
: String_List_Access
;
124 Is_Config_File
: Boolean;
125 Flags
: Processing_Flags
)
127 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
132 (Of_Kind
=> N_Project_Declaration
, In_Tree
=> In_Tree
);
133 Set_Location_Of
(Declarations
, In_Tree
, To
=> Token_Ptr
);
134 Set_Extended_Project_Of
(Declarations
, In_Tree
, To
=> Extends
);
135 Set_Project_Declaration_Of
(Current_Project
, In_Tree
, Declarations
);
136 Parse_Declarative_Items
137 (Declarations
=> First_Declarative_Item
,
139 In_Zone
=> In_Project
,
140 First_Attribute
=> Prj
.Attr
.Attribute_First
,
141 Current_Project
=> Current_Project
,
142 Current_Package
=> Empty_Node
,
143 Packages_To_Check
=> Packages_To_Check
,
144 Is_Config_File
=> Is_Config_File
,
146 Set_First_Declarative_Item_Of
147 (Declarations
, In_Tree
, To
=> First_Declarative_Item
);
150 ---------------------------------
151 -- Parse_Attribute_Declaration --
152 ---------------------------------
154 procedure Parse_Attribute_Declaration
155 (In_Tree
: Project_Node_Tree_Ref
;
156 Attribute
: out Project_Node_Id
;
157 First_Attribute
: Attribute_Node_Id
;
158 Current_Project
: Project_Node_Id
;
159 Current_Package
: Project_Node_Id
;
160 Packages_To_Check
: String_List_Access
;
161 Flags
: Processing_Flags
)
163 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
164 Full_Associative_Array
: Boolean := False;
165 Attribute_Name
: Name_Id
:= No_Name
;
166 Optional_Index
: Boolean := False;
167 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
168 Ignore
: Boolean := False;
173 (Of_Kind
=> N_Attribute_Declaration
, In_Tree
=> In_Tree
);
174 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
175 Set_Previous_Line_Node
(Attribute
);
181 -- Body may be an attribute name
183 if Token
= Tok_Body
then
184 Token
:= Tok_Identifier
;
185 Token_Name
:= Snames
.Name_Body
;
188 Expect
(Tok_Identifier
, "identifier");
190 if Token
= Tok_Identifier
then
191 Attribute_Name
:= Token_Name
;
192 Set_Name_Of
(Attribute
, In_Tree
, To
=> Token_Name
);
193 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
195 -- Find the attribute
198 Attribute_Node_Id_Of
(Token_Name
, First_Attribute
);
200 -- If the attribute cannot be found, create the attribute if inside
201 -- an unknown package.
203 if Current_Attribute
= Empty_Attribute
then
204 if Present
(Current_Package
)
205 and then Expression_Kind_Of
(Current_Package
, In_Tree
) = Ignored
207 Pkg_Id
:= Package_Id_Of
(Current_Package
, In_Tree
);
208 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
211 -- If not a valid attribute name, issue an error if inside
212 -- a package that need to be checked.
214 Ignore
:= Present
(Current_Package
) and then
215 Packages_To_Check
/= All_Packages
;
219 -- Check that we are not in a package to check
221 Get_Name_String
(Name_Of
(Current_Package
, In_Tree
));
223 for Index
in Packages_To_Check
'Range loop
224 if Name_Buffer
(1 .. Name_Len
) =
225 Packages_To_Check
(Index
).all
234 Error_Msg_Name_1
:= Token_Name
;
235 Error_Msg
(Flags
, "undefined attribute %%", Token_Ptr
);
239 -- Set, if appropriate the index case insensitivity flag
242 if Is_Read_Only
(Current_Attribute
) then
243 Error_Msg_Name_1
:= Token_Name
;
245 (Flags
, "read-only attribute %% cannot be given a value",
249 if Attribute_Kind_Of
(Current_Attribute
) in
250 Case_Insensitive_Associative_Array
..
251 Optional_Index_Case_Insensitive_Associative_Array
253 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
257 Scan
(In_Tree
); -- past the attribute name
260 -- Change obsolete names of attributes to the new names
262 if Present
(Current_Package
)
263 and then Expression_Kind_Of
(Current_Package
, In_Tree
) /= Ignored
265 case Name_Of
(Attribute
, In_Tree
) is
266 when Snames
.Name_Specification
=>
267 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec
);
269 when Snames
.Name_Specification_Suffix
=>
270 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec_Suffix
);
272 when Snames
.Name_Implementation
=>
273 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body
);
275 when Snames
.Name_Implementation_Suffix
=>
276 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body_Suffix
);
283 -- Associative array attributes
285 if Token
= Tok_Left_Paren
then
287 -- If the attribute is not an associative array attribute, report
288 -- an error. If this information is still unknown, set the kind
289 -- to Associative_Array.
291 if Current_Attribute
/= Empty_Attribute
292 and then Attribute_Kind_Of
(Current_Attribute
) = Single
297 (Attribute_Name_Of
(Current_Attribute
)) &
298 """ cannot be an associative array",
299 Location_Of
(Attribute
, In_Tree
));
301 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
302 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
305 Scan
(In_Tree
); -- past the left parenthesis
307 if Others_Allowed_For
(Current_Attribute
)
308 and then Token
= Tok_Others
310 Set_Associative_Array_Index_Of
311 (Attribute
, In_Tree
, All_Other_Names
);
312 Scan
(In_Tree
); -- past others
315 if Others_Allowed_For
(Current_Attribute
) then
316 Expect
(Tok_String_Literal
, "literal string or others");
318 Expect
(Tok_String_Literal
, "literal string");
321 if Token
= Tok_String_Literal
then
322 Get_Name_String
(Token_Name
);
324 if Case_Insensitive
(Attribute
, In_Tree
) then
325 To_Lower
(Name_Buffer
(1 .. Name_Len
));
328 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
329 Scan
(In_Tree
); -- past the literal string index
331 if Token
= Tok_At
then
332 case Attribute_Kind_Of
(Current_Attribute
) is
333 when Optional_Index_Associative_Array |
334 Optional_Index_Case_Insensitive_Associative_Array
=>
336 Expect
(Tok_Integer_Literal
, "integer literal");
338 if Token
= Tok_Integer_Literal
then
340 -- Set the source index value from given literal
343 Index
: constant Int
:=
344 UI_To_Int
(Int_Literal_Value
);
348 (Flags
, "index cannot be zero", Token_Ptr
);
351 (Attribute
, In_Tree
, To
=> Index
);
359 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
362 if Token
= Tok_Integer_Literal
then
370 Expect
(Tok_Right_Paren
, "`)`");
372 if Token
= Tok_Right_Paren
then
373 Scan
(In_Tree
); -- past the right parenthesis
377 -- If it is an associative array attribute and there are no left
378 -- parenthesis, then this is a full associative array declaration.
379 -- Flag it as such for later processing of its value.
381 if Current_Attribute
/= Empty_Attribute
383 Attribute_Kind_Of
(Current_Attribute
) /= Single
385 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
386 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
389 Full_Associative_Array
:= True;
394 -- Set the expression kind of the attribute
396 if Current_Attribute
/= Empty_Attribute
then
397 Set_Expression_Kind_Of
398 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
399 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
402 Expect
(Tok_Use
, "USE");
404 if Token
= Tok_Use
then
407 if Full_Associative_Array
then
409 -- Expect <project>'<same_attribute_name>, or
410 -- <project>.<same_package_name>'<same_attribute_name>
413 The_Project
: Project_Node_Id
:= Empty_Node
;
414 -- The node of the project where the associative array is
417 The_Package
: Project_Node_Id
:= Empty_Node
;
418 -- The node of the package where the associative array is
421 Project_Name
: Name_Id
:= No_Name
;
422 -- The name of the project where the associative array is
425 Location
: Source_Ptr
:= No_Location
;
426 -- The location of the project name
429 Expect
(Tok_Identifier
, "identifier");
431 if Token
= Tok_Identifier
then
432 Location
:= Token_Ptr
;
434 -- Find the project node in the imported project or
435 -- in the project being extended.
437 The_Project
:= Imported_Or_Extended_Project_Of
438 (Current_Project
, In_Tree
, Token_Name
);
440 if No
(The_Project
) then
441 Error_Msg
(Flags
, "unknown project", Location
);
442 Scan
(In_Tree
); -- past the project name
445 Project_Name
:= Token_Name
;
446 Scan
(In_Tree
); -- past the project name
448 -- If this is inside a package, a dot followed by the
449 -- name of the package must followed the project name.
451 if Present
(Current_Package
) then
452 Expect
(Tok_Dot
, "`.`");
454 if Token
/= Tok_Dot
then
455 The_Project
:= Empty_Node
;
458 Scan
(In_Tree
); -- past the dot
459 Expect
(Tok_Identifier
, "identifier");
461 if Token
/= Tok_Identifier
then
462 The_Project
:= Empty_Node
;
464 -- If it is not the same package name, issue error
467 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
469 The_Project
:= Empty_Node
;
471 (Flags
, "not the same package as " &
473 (Name_Of
(Current_Package
, In_Tree
)),
478 First_Package_Of
(The_Project
, In_Tree
);
480 -- Look for the package node
482 while Present
(The_Package
)
484 Name_Of
(The_Package
, In_Tree
) /= Token_Name
487 Next_Package_In_Project
488 (The_Package
, In_Tree
);
491 -- If the package cannot be found in the
492 -- project, issue an error.
494 if No
(The_Package
) then
495 The_Project
:= Empty_Node
;
496 Error_Msg_Name_2
:= Project_Name
;
497 Error_Msg_Name_1
:= Token_Name
;
500 "package % not declared in project %",
504 Scan
(In_Tree
); -- past the package name
511 if Present
(The_Project
) then
513 -- Looking for '<same attribute name>
515 Expect
(Tok_Apostrophe
, "`''`");
517 if Token
/= Tok_Apostrophe
then
518 The_Project
:= Empty_Node
;
521 Scan
(In_Tree
); -- past the apostrophe
522 Expect
(Tok_Identifier
, "identifier");
524 if Token
/= Tok_Identifier
then
525 The_Project
:= Empty_Node
;
528 -- If it is not the same attribute name, issue error
530 if Token_Name
/= Attribute_Name
then
531 The_Project
:= Empty_Node
;
532 Error_Msg_Name_1
:= Attribute_Name
;
534 (Flags
, "invalid name, should be %", Token_Ptr
);
537 Scan
(In_Tree
); -- past the attribute name
542 if No
(The_Project
) then
544 -- If there were any problem, set the attribute id to null,
545 -- so that the node will not be recorded.
547 Current_Attribute
:= Empty_Attribute
;
550 -- Set the appropriate field in the node.
551 -- Note that the index and the expression are nil. This
552 -- characterizes full associative array attribute
555 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
556 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
560 -- Other attribute declarations (not full associative array)
564 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
565 -- The location of the first token of the expression
567 Expression
: Project_Node_Id
:= Empty_Node
;
568 -- The expression, value for the attribute declaration
571 -- Get the expression value and set it in the attribute node
575 Expression
=> Expression
,
577 Current_Project
=> Current_Project
,
578 Current_Package
=> Current_Package
,
579 Optional_Index
=> Optional_Index
);
580 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
582 -- If the expression is legal, but not of the right kind
583 -- for the attribute, issue an error.
585 if Current_Attribute
/= Empty_Attribute
586 and then Present
(Expression
)
587 and then Variable_Kind_Of
(Current_Attribute
) /=
588 Expression_Kind_Of
(Expression
, In_Tree
)
590 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
593 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
597 (Flags
, "wrong expression kind for attribute """ &
599 (Attribute_Name_Of
(Current_Attribute
)) &
601 Expression_Location
);
608 -- If the attribute was not recognized, return an empty node.
609 -- It may be that it is not in a package to check, and the node will
610 -- not be added to the tree.
612 if Current_Attribute
= Empty_Attribute
then
613 Attribute
:= Empty_Node
;
616 Set_End_Of_Line
(Attribute
);
617 Set_Previous_Line_Node
(Attribute
);
618 end Parse_Attribute_Declaration
;
620 -----------------------------
621 -- Parse_Case_Construction --
622 -----------------------------
624 procedure Parse_Case_Construction
625 (In_Tree
: Project_Node_Tree_Ref
;
626 Case_Construction
: out Project_Node_Id
;
627 First_Attribute
: Attribute_Node_Id
;
628 Current_Project
: Project_Node_Id
;
629 Current_Package
: Project_Node_Id
;
630 Packages_To_Check
: String_List_Access
;
631 Is_Config_File
: Boolean;
632 Flags
: Processing_Flags
)
634 Current_Item
: Project_Node_Id
:= Empty_Node
;
635 Next_Item
: Project_Node_Id
:= Empty_Node
;
636 First_Case_Item
: Boolean := True;
638 Variable_Location
: Source_Ptr
:= No_Location
;
640 String_Type
: Project_Node_Id
:= Empty_Node
;
642 Case_Variable
: Project_Node_Id
:= Empty_Node
;
644 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
646 First_Choice
: Project_Node_Id
:= Empty_Node
;
648 When_Others
: Boolean := False;
649 -- Set to True when there is a "when others =>" clause
654 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
655 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
661 -- Get the switch variable
663 Expect
(Tok_Identifier
, "identifier");
665 if Token
= Tok_Identifier
then
666 Variable_Location
:= Token_Ptr
;
667 Parse_Variable_Reference
669 Variable
=> Case_Variable
,
671 Current_Project
=> Current_Project
,
672 Current_Package
=> Current_Package
);
673 Set_Case_Variable_Reference_Of
674 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
677 if Token
/= Tok_Is
then
682 if Present
(Case_Variable
) then
683 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
685 if No
(String_Type
) then
688 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
694 Expect
(Tok_Is
, "IS");
696 if Token
= Tok_Is
then
697 Set_End_Of_Line
(Case_Construction
);
698 Set_Previous_Line_Node
(Case_Construction
);
699 Set_Next_End_Node
(Case_Construction
);
706 Start_New_Case_Construction
(In_Tree
, String_Type
);
710 while Token
= Tok_When
loop
712 if First_Case_Item
then
715 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
716 Set_First_Case_Item_Of
717 (Case_Construction
, In_Tree
, To
=> Current_Item
);
718 First_Case_Item
:= False;
723 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
724 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
725 Current_Item
:= Next_Item
;
728 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
734 if Token
= Tok_Others
then
737 -- Scan past "others"
741 Expect
(Tok_Arrow
, "`=>`");
742 Set_End_Of_Line
(Current_Item
);
743 Set_Previous_Line_Node
(Current_Item
);
745 -- Empty_Node in Field1 of a Case_Item indicates
746 -- the "when others =>" branch.
748 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
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
,
758 Is_Config_File
=> Is_Config_File
,
761 -- "when others =>" must be the last branch, so save the
762 -- Case_Item and exit
764 Set_First_Declarative_Item_Of
765 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
771 First_Choice
=> First_Choice
,
773 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
775 Expect
(Tok_Arrow
, "`=>`");
776 Set_End_Of_Line
(Current_Item
);
777 Set_Previous_Line_Node
(Current_Item
);
779 Parse_Declarative_Items
781 Declarations
=> First_Declarative_Item
,
782 In_Zone
=> In_Case_Construction
,
783 First_Attribute
=> First_Attribute
,
784 Current_Project
=> Current_Project
,
785 Current_Package
=> Current_Package
,
786 Packages_To_Check
=> Packages_To_Check
,
787 Is_Config_File
=> Is_Config_File
,
790 Set_First_Declarative_Item_Of
791 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
796 End_Case_Construction
797 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
798 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
801 Expect
(Tok_End
, "`END CASE`");
802 Remove_Next_End_Node
;
804 if Token
= Tok_End
then
810 Expect
(Tok_Case
, "CASE");
818 Expect
(Tok_Semicolon
, "`;`");
819 Set_Previous_End_Node
(Case_Construction
);
821 end Parse_Case_Construction
;
823 -----------------------------
824 -- Parse_Declarative_Items --
825 -----------------------------
827 procedure Parse_Declarative_Items
828 (In_Tree
: Project_Node_Tree_Ref
;
829 Declarations
: out Project_Node_Id
;
831 First_Attribute
: Attribute_Node_Id
;
832 Current_Project
: Project_Node_Id
;
833 Current_Package
: Project_Node_Id
;
834 Packages_To_Check
: String_List_Access
;
835 Is_Config_File
: Boolean;
836 Flags
: Processing_Flags
)
838 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
839 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
840 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
841 Item_Location
: Source_Ptr
:= No_Location
;
844 Declarations
:= Empty_Node
;
847 -- We are always positioned at the token that precedes the first
848 -- token of the declarative element. Scan past it.
852 Item_Location
:= Token_Ptr
;
855 when Tok_Identifier
=>
857 if In_Zone
= In_Case_Construction
then
859 -- Check if the variable has already been declared
862 The_Variable
: Project_Node_Id
:= Empty_Node
;
865 if Present
(Current_Package
) then
867 First_Variable_Of
(Current_Package
, In_Tree
);
868 elsif Present
(Current_Project
) then
870 First_Variable_Of
(Current_Project
, In_Tree
);
873 while Present
(The_Variable
)
874 and then Name_Of
(The_Variable
, In_Tree
) /=
877 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
880 -- It is an error to declare a variable in a case
881 -- construction for the first time.
883 if No
(The_Variable
) then
886 "a variable cannot be declared " &
887 "for the first time here",
893 Parse_Variable_Declaration
896 Current_Project
=> Current_Project
,
897 Current_Package
=> Current_Package
,
900 Set_End_Of_Line
(Current_Declaration
);
901 Set_Previous_Line_Node
(Current_Declaration
);
905 Parse_Attribute_Declaration
907 Attribute
=> Current_Declaration
,
908 First_Attribute
=> First_Attribute
,
909 Current_Project
=> Current_Project
,
910 Current_Package
=> Current_Package
,
911 Packages_To_Check
=> Packages_To_Check
,
914 Set_End_Of_Line
(Current_Declaration
);
915 Set_Previous_Line_Node
(Current_Declaration
);
919 Scan
(In_Tree
); -- past "null"
923 -- Package declaration
925 if In_Zone
/= In_Project
then
927 (Flags
, "a package cannot be declared here", Token_Ptr
);
930 Parse_Package_Declaration
932 Package_Declaration
=> Current_Declaration
,
933 Current_Project
=> Current_Project
,
934 Packages_To_Check
=> Packages_To_Check
,
935 Is_Config_File
=> Is_Config_File
,
938 Set_Previous_End_Node
(Current_Declaration
);
942 -- Type String Declaration
944 if In_Zone
/= In_Project
then
946 "a string type cannot be declared here",
950 Parse_String_Type_Declaration
952 String_Type
=> Current_Declaration
,
953 Current_Project
=> Current_Project
,
956 Set_End_Of_Line
(Current_Declaration
);
957 Set_Previous_Line_Node
(Current_Declaration
);
963 Parse_Case_Construction
965 Case_Construction
=> Current_Declaration
,
966 First_Attribute
=> First_Attribute
,
967 Current_Project
=> Current_Project
,
968 Current_Package
=> Current_Package
,
969 Packages_To_Check
=> Packages_To_Check
,
970 Is_Config_File
=> Is_Config_File
,
973 Set_Previous_End_Node
(Current_Declaration
);
978 -- We are leaving Parse_Declarative_Items positioned
979 -- at the first token after the list of declarative items.
980 -- It could be "end" (for a project, a package declaration or
981 -- a case construction) or "when" (for a case construction)
985 Expect
(Tok_Semicolon
, "`;` after declarative items");
987 -- Insert an N_Declarative_Item in the tree, but only if
988 -- Current_Declaration is not an empty node.
990 if Present
(Current_Declaration
) then
991 if No
(Current_Declarative_Item
) then
992 Current_Declarative_Item
:=
994 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
995 Declarations
:= Current_Declarative_Item
;
998 Next_Declarative_Item
:=
1000 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1001 Set_Next_Declarative_Item
1002 (Current_Declarative_Item
, In_Tree
,
1003 To
=> Next_Declarative_Item
);
1004 Current_Declarative_Item
:= Next_Declarative_Item
;
1007 Set_Current_Item_Node
1008 (Current_Declarative_Item
, In_Tree
,
1009 To
=> Current_Declaration
);
1011 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1014 end Parse_Declarative_Items
;
1016 -------------------------------
1017 -- Parse_Package_Declaration --
1018 -------------------------------
1020 procedure Parse_Package_Declaration
1021 (In_Tree
: Project_Node_Tree_Ref
;
1022 Package_Declaration
: out Project_Node_Id
;
1023 Current_Project
: Project_Node_Id
;
1024 Packages_To_Check
: String_List_Access
;
1025 Is_Config_File
: Boolean;
1026 Flags
: Processing_Flags
)
1028 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1029 Current_Package
: Package_Node_Id
:= Empty_Package
;
1030 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1032 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1035 Package_Declaration
:=
1036 Default_Project_Node
1037 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1038 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1040 -- Scan past "package"
1043 Expect
(Tok_Identifier
, "identifier");
1045 if Token
= Tok_Identifier
then
1046 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1048 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1050 if Current_Package
= Empty_Package
then
1051 if not Quiet_Output
then
1053 List
: constant Strings
.String_List
:= Package_Name_List
;
1055 Name
: constant String := Get_Name_String
(Token_Name
);
1058 -- Check for possible misspelling of a known package name
1062 if Index
>= List
'Last then
1069 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1070 (Name
, List
(Index
).all);
1073 -- Issue warning(s) in verbose mode or when a possible
1074 -- misspelling has been found.
1076 if Verbose_Mode
or else Index
/= 0 then
1080 (Name_Of
(Package_Declaration
, In_Tree
)) &
1081 """ is not a known package name",
1086 Error_Msg
-- CODEFIX
1088 "\?possible misspelling of """ &
1089 List
(Index
).all & """", Token_Ptr
);
1094 -- Set the package declaration to "ignored" so that it is not
1095 -- processed by Prj.Proc.Process.
1097 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1099 -- Add the unknown package in the list of packages
1101 Add_Unknown_Package
(Token_Name
, Current_Package
);
1103 elsif Current_Package
= Unknown_Package
then
1105 -- Set the package declaration to "ignored" so that it is not
1106 -- processed by Prj.Proc.Process.
1108 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1111 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1115 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1118 Current
: Project_Node_Id
:=
1119 First_Package_Of
(Current_Project
, In_Tree
);
1122 while Present
(Current
)
1123 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1125 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1128 if Present
(Current
) then
1132 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1133 """ is declared twice in the same project",
1137 -- Add the package to the project list
1139 Set_Next_Package_In_Project
1140 (Package_Declaration
, In_Tree
,
1141 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1142 Set_First_Package_Of
1143 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1147 -- Scan past the package name
1152 if Token
= Tok_Renames
then
1153 if Is_Config_File
then
1156 "no package renames in configuration projects", Token_Ptr
);
1159 -- Scan past "renames"
1163 Expect
(Tok_Identifier
, "identifier");
1165 if Token
= Tok_Identifier
then
1167 Project_Name
: constant Name_Id
:= Token_Name
;
1169 Clause
: Project_Node_Id
:=
1170 First_With_Clause_Of
(Current_Project
, In_Tree
);
1171 The_Project
: Project_Node_Id
:= Empty_Node
;
1172 Extended
: constant Project_Node_Id
:=
1174 (Project_Declaration_Of
1175 (Current_Project
, In_Tree
),
1178 while Present
(Clause
) loop
1179 -- Only non limited imported projects may be used in a
1180 -- renames declaration.
1183 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1184 exit when Present
(The_Project
)
1185 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1186 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1190 -- As we have not found the project in the imports, we check
1191 -- if it's the name of an eventual extended project.
1193 if Present
(Extended
)
1194 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1196 Set_Project_Of_Renamed_Package_Of
1197 (Package_Declaration
, In_Tree
, To
=> Extended
);
1199 Error_Msg_Name_1
:= Project_Name
;
1202 "% is not an imported or extended project", Token_Ptr
);
1205 Set_Project_Of_Renamed_Package_Of
1206 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1211 Expect
(Tok_Dot
, "`.`");
1213 if Token
= Tok_Dot
then
1215 Expect
(Tok_Identifier
, "identifier");
1217 if Token
= Tok_Identifier
then
1218 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1219 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1221 Present
(Project_Of_Renamed_Package_Of
1222 (Package_Declaration
, In_Tree
))
1225 Current
: Project_Node_Id
:=
1227 (Project_Of_Renamed_Package_Of
1228 (Package_Declaration
, In_Tree
),
1232 while Present
(Current
)
1233 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1236 Next_Package_In_Project
(Current
, In_Tree
);
1239 if No
(Current
) then
1242 Get_Name_String
(Token_Name
) &
1243 """ is not a package declared by the project",
1254 Expect
(Tok_Semicolon
, "`;`");
1255 Set_End_Of_Line
(Package_Declaration
);
1256 Set_Previous_Line_Node
(Package_Declaration
);
1258 elsif Token
= Tok_Is
then
1259 Set_End_Of_Line
(Package_Declaration
);
1260 Set_Previous_Line_Node
(Package_Declaration
);
1261 Set_Next_End_Node
(Package_Declaration
);
1263 Parse_Declarative_Items
1264 (In_Tree
=> In_Tree
,
1265 Declarations
=> First_Declarative_Item
,
1266 In_Zone
=> In_Package
,
1267 First_Attribute
=> First_Attribute
,
1268 Current_Project
=> Current_Project
,
1269 Current_Package
=> Package_Declaration
,
1270 Packages_To_Check
=> Packages_To_Check
,
1271 Is_Config_File
=> Is_Config_File
,
1274 Set_First_Declarative_Item_Of
1275 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1277 Expect
(Tok_End
, "END");
1279 if Token
= Tok_End
then
1286 -- We should have the name of the package after "end"
1288 Expect
(Tok_Identifier
, "identifier");
1290 if Token
= Tok_Identifier
1291 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1292 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1294 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1295 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1298 if Token
/= Tok_Semicolon
then
1300 -- Scan past the package name
1305 Expect
(Tok_Semicolon
, "`;`");
1306 Remove_Next_End_Node
;
1309 Error_Msg
(Flags
, "expected IS or RENAMES", Token_Ptr
);
1312 end Parse_Package_Declaration
;
1314 -----------------------------------
1315 -- Parse_String_Type_Declaration --
1316 -----------------------------------
1318 procedure Parse_String_Type_Declaration
1319 (In_Tree
: Project_Node_Tree_Ref
;
1320 String_Type
: out Project_Node_Id
;
1321 Current_Project
: Project_Node_Id
;
1322 Flags
: Processing_Flags
)
1324 Current
: Project_Node_Id
:= Empty_Node
;
1325 First_String
: Project_Node_Id
:= Empty_Node
;
1329 Default_Project_Node
1330 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1332 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1338 Expect
(Tok_Identifier
, "identifier");
1340 if Token
= Tok_Identifier
then
1341 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1343 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1344 while Present
(Current
)
1346 Name_Of
(Current
, In_Tree
) /= Token_Name
1348 Current
:= Next_String_Type
(Current
, In_Tree
);
1351 if Present
(Current
) then
1353 "duplicate string type name """ &
1354 Get_Name_String
(Token_Name
) &
1358 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1359 while Present
(Current
)
1360 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1362 Current
:= Next_Variable
(Current
, In_Tree
);
1365 if Present
(Current
) then
1368 Get_Name_String
(Token_Name
) &
1369 """ is already a variable name", Token_Ptr
);
1371 Set_Next_String_Type
1372 (String_Type
, In_Tree
,
1373 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1374 Set_First_String_Type_Of
1375 (Current_Project
, In_Tree
, To
=> String_Type
);
1379 -- Scan past the name
1384 Expect
(Tok_Is
, "IS");
1386 if Token
= Tok_Is
then
1390 Expect
(Tok_Left_Paren
, "`(`");
1392 if Token
= Tok_Left_Paren
then
1396 Parse_String_Type_List
1397 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1398 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1400 Expect
(Tok_Right_Paren
, "`)`");
1402 if Token
= Tok_Right_Paren
then
1406 end Parse_String_Type_Declaration
;
1408 --------------------------------
1409 -- Parse_Variable_Declaration --
1410 --------------------------------
1412 procedure Parse_Variable_Declaration
1413 (In_Tree
: Project_Node_Tree_Ref
;
1414 Variable
: out Project_Node_Id
;
1415 Current_Project
: Project_Node_Id
;
1416 Current_Package
: Project_Node_Id
;
1417 Flags
: Processing_Flags
)
1419 Expression_Location
: Source_Ptr
;
1420 String_Type_Name
: Name_Id
:= No_Name
;
1421 Project_String_Type_Name
: Name_Id
:= No_Name
;
1422 Type_Location
: Source_Ptr
:= No_Location
;
1423 Project_Location
: Source_Ptr
:= No_Location
;
1424 Expression
: Project_Node_Id
:= Empty_Node
;
1425 Variable_Name
: constant Name_Id
:= Token_Name
;
1426 OK
: Boolean := True;
1430 Default_Project_Node
1431 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1432 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1433 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1435 -- Scan past the variable name
1439 if Token
= Tok_Colon
then
1441 -- Typed string variable declaration
1444 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1445 Expect
(Tok_Identifier
, "identifier");
1447 OK
:= Token
= Tok_Identifier
;
1450 String_Type_Name
:= Token_Name
;
1451 Type_Location
:= Token_Ptr
;
1454 if Token
= Tok_Dot
then
1455 Project_String_Type_Name
:= String_Type_Name
;
1456 Project_Location
:= Type_Location
;
1458 -- Scan past the dot
1461 Expect
(Tok_Identifier
, "identifier");
1463 if Token
= Tok_Identifier
then
1464 String_Type_Name
:= Token_Name
;
1465 Type_Location
:= Token_Ptr
;
1474 Proj
: Project_Node_Id
:= Current_Project
;
1475 Current
: Project_Node_Id
:= Empty_Node
;
1478 if Project_String_Type_Name
/= No_Name
then
1480 The_Project_Name_And_Node
: constant
1481 Tree_Private_Part
.Project_Name_And_Node
:=
1482 Tree_Private_Part
.Projects_Htable
.Get
1483 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1485 use Tree_Private_Part
;
1488 if The_Project_Name_And_Node
=
1489 Tree_Private_Part
.No_Project_Name_And_Node
1492 "unknown project """ &
1494 (Project_String_Type_Name
) &
1497 Current
:= Empty_Node
;
1500 First_String_Type_Of
1501 (The_Project_Name_And_Node
.Node
, In_Tree
);
1505 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1507 Current
:= Next_String_Type
(Current
, In_Tree
);
1513 -- Look for a string type with the correct name in this
1514 -- project or in any of its ancestors.
1518 First_String_Type_Of
(Proj
, In_Tree
);
1522 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1524 Current
:= Next_String_Type
(Current
, In_Tree
);
1527 exit when Present
(Current
);
1529 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1530 exit when No
(Proj
);
1534 if No
(Current
) then
1536 "unknown string type """ &
1537 Get_Name_String
(String_Type_Name
) &
1544 (Variable
, In_Tree
, To
=> Current
);
1551 Expect
(Tok_Colon_Equal
, "`:=`");
1553 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1555 if Token
= Tok_Colon_Equal
then
1559 -- Get the single string or string list value
1561 Expression_Location
:= Token_Ptr
;
1564 (In_Tree
=> In_Tree
,
1565 Expression
=> Expression
,
1567 Current_Project
=> Current_Project
,
1568 Current_Package
=> Current_Package
,
1569 Optional_Index
=> False);
1570 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1572 if Present
(Expression
) then
1573 -- A typed string must have a single string value, not a list
1575 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1576 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1580 "expression must be a single string", Expression_Location
);
1583 Set_Expression_Kind_Of
1585 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1590 The_Variable
: Project_Node_Id
:= Empty_Node
;
1593 if Present
(Current_Package
) then
1594 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1595 elsif Present
(Current_Project
) then
1596 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1599 while Present
(The_Variable
)
1600 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1602 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1605 if No
(The_Variable
) then
1606 if Present
(Current_Package
) then
1609 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1610 Set_First_Variable_Of
1611 (Current_Package
, In_Tree
, To
=> Variable
);
1613 elsif Present
(Current_Project
) then
1616 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1617 Set_First_Variable_Of
1618 (Current_Project
, In_Tree
, To
=> Variable
);
1622 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1623 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1626 Set_Expression_Kind_Of
1627 (The_Variable
, In_Tree
,
1628 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1631 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1632 Expression_Kind_Of
(Variable
, In_Tree
)
1635 "wrong expression kind for variable """ &
1637 (Name_Of
(The_Variable
, In_Tree
)) &
1639 Expression_Location
);
1646 end Parse_Variable_Declaration
;