1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2010, 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 All_Case_Insensitive_Associative_Array
252 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
256 Scan
(In_Tree
); -- past the attribute name
259 -- Change obsolete names of attributes to the new names
261 if Present
(Current_Package
)
262 and then Expression_Kind_Of
(Current_Package
, In_Tree
) /= Ignored
264 case Name_Of
(Attribute
, In_Tree
) is
265 when Snames
.Name_Specification
=>
266 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec
);
268 when Snames
.Name_Specification_Suffix
=>
269 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec_Suffix
);
271 when Snames
.Name_Implementation
=>
272 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body
);
274 when Snames
.Name_Implementation_Suffix
=>
275 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body_Suffix
);
282 -- Associative array attributes
284 if Token
= Tok_Left_Paren
then
286 -- If the attribute is not an associative array attribute, report
287 -- an error. If this information is still unknown, set the kind
288 -- to Associative_Array.
290 if Current_Attribute
/= Empty_Attribute
291 and then Attribute_Kind_Of
(Current_Attribute
) = Single
296 (Attribute_Name_Of
(Current_Attribute
)) &
297 """ cannot be an associative array",
298 Location_Of
(Attribute
, In_Tree
));
300 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
301 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
304 Scan
(In_Tree
); -- past the left parenthesis
306 if Others_Allowed_For
(Current_Attribute
)
307 and then Token
= Tok_Others
309 Set_Associative_Array_Index_Of
310 (Attribute
, In_Tree
, All_Other_Names
);
311 Scan
(In_Tree
); -- past others
314 if Others_Allowed_For
(Current_Attribute
) then
315 Expect
(Tok_String_Literal
, "literal string or others");
317 Expect
(Tok_String_Literal
, "literal string");
320 if Token
= Tok_String_Literal
then
321 Get_Name_String
(Token_Name
);
323 if Case_Insensitive
(Attribute
, In_Tree
) then
324 To_Lower
(Name_Buffer
(1 .. Name_Len
));
327 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
328 Scan
(In_Tree
); -- past the literal string index
330 if Token
= Tok_At
then
331 case Attribute_Kind_Of
(Current_Attribute
) is
332 when Optional_Index_Associative_Array |
333 Optional_Index_Case_Insensitive_Associative_Array
=>
335 Expect
(Tok_Integer_Literal
, "integer literal");
337 if Token
= Tok_Integer_Literal
then
339 -- Set the source index value from given literal
342 Index
: constant Int
:=
343 UI_To_Int
(Int_Literal_Value
);
347 (Flags
, "index cannot be zero", Token_Ptr
);
350 (Attribute
, In_Tree
, To
=> Index
);
358 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
361 if Token
= Tok_Integer_Literal
then
369 Expect
(Tok_Right_Paren
, "`)`");
371 if Token
= Tok_Right_Paren
then
372 Scan
(In_Tree
); -- past the right parenthesis
376 -- If it is an associative array attribute and there are no left
377 -- parenthesis, then this is a full associative array declaration.
378 -- Flag it as such for later processing of its value.
380 if Current_Attribute
/= Empty_Attribute
382 Attribute_Kind_Of
(Current_Attribute
) /= Single
384 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
385 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
388 Full_Associative_Array
:= True;
393 -- Set the expression kind of the attribute
395 if Current_Attribute
/= Empty_Attribute
then
396 Set_Expression_Kind_Of
397 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
398 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
401 Expect
(Tok_Use
, "USE");
403 if Token
= Tok_Use
then
406 if Full_Associative_Array
then
408 -- Expect <project>'<same_attribute_name>, or
409 -- <project>.<same_package_name>'<same_attribute_name>
412 The_Project
: Project_Node_Id
:= Empty_Node
;
413 -- The node of the project where the associative array is
416 The_Package
: Project_Node_Id
:= Empty_Node
;
417 -- The node of the package where the associative array is
420 Project_Name
: Name_Id
:= No_Name
;
421 -- The name of the project where the associative array is
424 Location
: Source_Ptr
:= No_Location
;
425 -- The location of the project name
428 Expect
(Tok_Identifier
, "identifier");
430 if Token
= Tok_Identifier
then
431 Location
:= Token_Ptr
;
433 -- Find the project node in the imported project or
434 -- in the project being extended.
436 The_Project
:= Imported_Or_Extended_Project_Of
437 (Current_Project
, In_Tree
, Token_Name
);
439 if No
(The_Project
) then
440 Error_Msg
(Flags
, "unknown project", Location
);
441 Scan
(In_Tree
); -- past the project name
444 Project_Name
:= Token_Name
;
445 Scan
(In_Tree
); -- past the project name
447 -- If this is inside a package, a dot followed by the
448 -- name of the package must followed the project name.
450 if Present
(Current_Package
) then
451 Expect
(Tok_Dot
, "`.`");
453 if Token
/= Tok_Dot
then
454 The_Project
:= Empty_Node
;
457 Scan
(In_Tree
); -- past the dot
458 Expect
(Tok_Identifier
, "identifier");
460 if Token
/= Tok_Identifier
then
461 The_Project
:= Empty_Node
;
463 -- If it is not the same package name, issue error
466 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
468 The_Project
:= Empty_Node
;
470 (Flags
, "not the same package as " &
472 (Name_Of
(Current_Package
, In_Tree
)),
477 First_Package_Of
(The_Project
, In_Tree
);
479 -- Look for the package node
481 while Present
(The_Package
)
483 Name_Of
(The_Package
, In_Tree
) /= Token_Name
486 Next_Package_In_Project
487 (The_Package
, In_Tree
);
490 -- If the package cannot be found in the
491 -- project, issue an error.
493 if No
(The_Package
) then
494 The_Project
:= Empty_Node
;
495 Error_Msg_Name_2
:= Project_Name
;
496 Error_Msg_Name_1
:= Token_Name
;
499 "package % not declared in project %",
503 Scan
(In_Tree
); -- past the package name
510 if Present
(The_Project
) then
512 -- Looking for '<same attribute name>
514 Expect
(Tok_Apostrophe
, "`''`");
516 if Token
/= Tok_Apostrophe
then
517 The_Project
:= Empty_Node
;
520 Scan
(In_Tree
); -- past the apostrophe
521 Expect
(Tok_Identifier
, "identifier");
523 if Token
/= Tok_Identifier
then
524 The_Project
:= Empty_Node
;
527 -- If it is not the same attribute name, issue error
529 if Token_Name
/= Attribute_Name
then
530 The_Project
:= Empty_Node
;
531 Error_Msg_Name_1
:= Attribute_Name
;
533 (Flags
, "invalid name, should be %", Token_Ptr
);
536 Scan
(In_Tree
); -- past the attribute name
541 if No
(The_Project
) then
543 -- If there were any problem, set the attribute id to null,
544 -- so that the node will not be recorded.
546 Current_Attribute
:= Empty_Attribute
;
549 -- Set the appropriate field in the node.
550 -- Note that the index and the expression are nil. This
551 -- characterizes full associative array attribute
554 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
555 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
559 -- Other attribute declarations (not full associative array)
563 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
564 -- The location of the first token of the expression
566 Expression
: Project_Node_Id
:= Empty_Node
;
567 -- The expression, value for the attribute declaration
570 -- Get the expression value and set it in the attribute node
574 Expression
=> Expression
,
576 Current_Project
=> Current_Project
,
577 Current_Package
=> Current_Package
,
578 Optional_Index
=> Optional_Index
);
579 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
581 -- If the expression is legal, but not of the right kind
582 -- for the attribute, issue an error.
584 if Current_Attribute
/= Empty_Attribute
585 and then Present
(Expression
)
586 and then Variable_Kind_Of
(Current_Attribute
) /=
587 Expression_Kind_Of
(Expression
, In_Tree
)
589 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
592 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
596 (Flags
, "wrong expression kind for attribute """ &
598 (Attribute_Name_Of
(Current_Attribute
)) &
600 Expression_Location
);
607 -- If the attribute was not recognized, return an empty node.
608 -- It may be that it is not in a package to check, and the node will
609 -- not be added to the tree.
611 if Current_Attribute
= Empty_Attribute
then
612 Attribute
:= Empty_Node
;
615 Set_End_Of_Line
(Attribute
);
616 Set_Previous_Line_Node
(Attribute
);
617 end Parse_Attribute_Declaration
;
619 -----------------------------
620 -- Parse_Case_Construction --
621 -----------------------------
623 procedure Parse_Case_Construction
624 (In_Tree
: Project_Node_Tree_Ref
;
625 Case_Construction
: out Project_Node_Id
;
626 First_Attribute
: Attribute_Node_Id
;
627 Current_Project
: Project_Node_Id
;
628 Current_Package
: Project_Node_Id
;
629 Packages_To_Check
: String_List_Access
;
630 Is_Config_File
: Boolean;
631 Flags
: Processing_Flags
)
633 Current_Item
: Project_Node_Id
:= Empty_Node
;
634 Next_Item
: Project_Node_Id
:= Empty_Node
;
635 First_Case_Item
: Boolean := True;
637 Variable_Location
: Source_Ptr
:= No_Location
;
639 String_Type
: Project_Node_Id
:= Empty_Node
;
641 Case_Variable
: Project_Node_Id
:= Empty_Node
;
643 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
645 First_Choice
: Project_Node_Id
:= Empty_Node
;
647 When_Others
: Boolean := False;
648 -- Set to True when there is a "when others =>" clause
653 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
654 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
660 -- Get the switch variable
662 Expect
(Tok_Identifier
, "identifier");
664 if Token
= Tok_Identifier
then
665 Variable_Location
:= Token_Ptr
;
666 Parse_Variable_Reference
668 Variable
=> Case_Variable
,
670 Current_Project
=> Current_Project
,
671 Current_Package
=> Current_Package
);
672 Set_Case_Variable_Reference_Of
673 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
676 if Token
/= Tok_Is
then
681 if Present
(Case_Variable
) then
682 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
684 if No
(String_Type
) then
687 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
693 Expect
(Tok_Is
, "IS");
695 if Token
= Tok_Is
then
696 Set_End_Of_Line
(Case_Construction
);
697 Set_Previous_Line_Node
(Case_Construction
);
698 Set_Next_End_Node
(Case_Construction
);
705 Start_New_Case_Construction
(In_Tree
, String_Type
);
709 while Token
= Tok_When
loop
711 if First_Case_Item
then
714 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
715 Set_First_Case_Item_Of
716 (Case_Construction
, In_Tree
, To
=> Current_Item
);
717 First_Case_Item
:= False;
722 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
723 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
724 Current_Item
:= Next_Item
;
727 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
733 if Token
= Tok_Others
then
736 -- Scan past "others"
740 Expect
(Tok_Arrow
, "`=>`");
741 Set_End_Of_Line
(Current_Item
);
742 Set_Previous_Line_Node
(Current_Item
);
744 -- Empty_Node in Field1 of a Case_Item indicates
745 -- the "when others =>" branch.
747 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
749 Parse_Declarative_Items
751 Declarations
=> First_Declarative_Item
,
752 In_Zone
=> In_Case_Construction
,
753 First_Attribute
=> First_Attribute
,
754 Current_Project
=> Current_Project
,
755 Current_Package
=> Current_Package
,
756 Packages_To_Check
=> Packages_To_Check
,
757 Is_Config_File
=> Is_Config_File
,
760 -- "when others =>" must be the last branch, so save the
761 -- Case_Item and exit
763 Set_First_Declarative_Item_Of
764 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
770 First_Choice
=> First_Choice
,
772 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
774 Expect
(Tok_Arrow
, "`=>`");
775 Set_End_Of_Line
(Current_Item
);
776 Set_Previous_Line_Node
(Current_Item
);
778 Parse_Declarative_Items
780 Declarations
=> First_Declarative_Item
,
781 In_Zone
=> In_Case_Construction
,
782 First_Attribute
=> First_Attribute
,
783 Current_Project
=> Current_Project
,
784 Current_Package
=> Current_Package
,
785 Packages_To_Check
=> Packages_To_Check
,
786 Is_Config_File
=> Is_Config_File
,
789 Set_First_Declarative_Item_Of
790 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
795 End_Case_Construction
796 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
797 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
800 Expect
(Tok_End
, "`END CASE`");
801 Remove_Next_End_Node
;
803 if Token
= Tok_End
then
809 Expect
(Tok_Case
, "CASE");
817 Expect
(Tok_Semicolon
, "`;`");
818 Set_Previous_End_Node
(Case_Construction
);
820 end Parse_Case_Construction
;
822 -----------------------------
823 -- Parse_Declarative_Items --
824 -----------------------------
826 procedure Parse_Declarative_Items
827 (In_Tree
: Project_Node_Tree_Ref
;
828 Declarations
: out Project_Node_Id
;
830 First_Attribute
: Attribute_Node_Id
;
831 Current_Project
: Project_Node_Id
;
832 Current_Package
: Project_Node_Id
;
833 Packages_To_Check
: String_List_Access
;
834 Is_Config_File
: Boolean;
835 Flags
: Processing_Flags
)
837 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
838 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
839 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
840 Item_Location
: Source_Ptr
:= No_Location
;
843 Declarations
:= Empty_Node
;
846 -- We are always positioned at the token that precedes the first
847 -- token of the declarative element. Scan past it.
851 Item_Location
:= Token_Ptr
;
854 when Tok_Identifier
=>
856 if In_Zone
= In_Case_Construction
then
858 -- Check if the variable has already been declared
861 The_Variable
: Project_Node_Id
:= Empty_Node
;
864 if Present
(Current_Package
) then
866 First_Variable_Of
(Current_Package
, In_Tree
);
867 elsif Present
(Current_Project
) then
869 First_Variable_Of
(Current_Project
, In_Tree
);
872 while Present
(The_Variable
)
873 and then Name_Of
(The_Variable
, In_Tree
) /=
876 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
879 -- It is an error to declare a variable in a case
880 -- construction for the first time.
882 if No
(The_Variable
) then
885 "a variable cannot be declared " &
886 "for the first time here",
892 Parse_Variable_Declaration
895 Current_Project
=> Current_Project
,
896 Current_Package
=> Current_Package
,
899 Set_End_Of_Line
(Current_Declaration
);
900 Set_Previous_Line_Node
(Current_Declaration
);
904 Parse_Attribute_Declaration
906 Attribute
=> Current_Declaration
,
907 First_Attribute
=> First_Attribute
,
908 Current_Project
=> Current_Project
,
909 Current_Package
=> Current_Package
,
910 Packages_To_Check
=> Packages_To_Check
,
913 Set_End_Of_Line
(Current_Declaration
);
914 Set_Previous_Line_Node
(Current_Declaration
);
918 Scan
(In_Tree
); -- past "null"
922 -- Package declaration
924 if In_Zone
/= In_Project
then
926 (Flags
, "a package cannot be declared here", Token_Ptr
);
929 Parse_Package_Declaration
931 Package_Declaration
=> Current_Declaration
,
932 Current_Project
=> Current_Project
,
933 Packages_To_Check
=> Packages_To_Check
,
934 Is_Config_File
=> Is_Config_File
,
937 Set_Previous_End_Node
(Current_Declaration
);
941 -- Type String Declaration
943 if In_Zone
/= In_Project
then
945 "a string type cannot be declared here",
949 Parse_String_Type_Declaration
951 String_Type
=> Current_Declaration
,
952 Current_Project
=> Current_Project
,
955 Set_End_Of_Line
(Current_Declaration
);
956 Set_Previous_Line_Node
(Current_Declaration
);
962 Parse_Case_Construction
964 Case_Construction
=> Current_Declaration
,
965 First_Attribute
=> First_Attribute
,
966 Current_Project
=> Current_Project
,
967 Current_Package
=> Current_Package
,
968 Packages_To_Check
=> Packages_To_Check
,
969 Is_Config_File
=> Is_Config_File
,
972 Set_Previous_End_Node
(Current_Declaration
);
977 -- We are leaving Parse_Declarative_Items positioned
978 -- at the first token after the list of declarative items.
979 -- It could be "end" (for a project, a package declaration or
980 -- a case construction) or "when" (for a case construction)
984 Expect
(Tok_Semicolon
, "`;` after declarative items");
986 -- Insert an N_Declarative_Item in the tree, but only if
987 -- Current_Declaration is not an empty node.
989 if Present
(Current_Declaration
) then
990 if No
(Current_Declarative_Item
) then
991 Current_Declarative_Item
:=
993 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
994 Declarations
:= Current_Declarative_Item
;
997 Next_Declarative_Item
:=
999 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1000 Set_Next_Declarative_Item
1001 (Current_Declarative_Item
, In_Tree
,
1002 To
=> Next_Declarative_Item
);
1003 Current_Declarative_Item
:= Next_Declarative_Item
;
1006 Set_Current_Item_Node
1007 (Current_Declarative_Item
, In_Tree
,
1008 To
=> Current_Declaration
);
1010 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1013 end Parse_Declarative_Items
;
1015 -------------------------------
1016 -- Parse_Package_Declaration --
1017 -------------------------------
1019 procedure Parse_Package_Declaration
1020 (In_Tree
: Project_Node_Tree_Ref
;
1021 Package_Declaration
: out Project_Node_Id
;
1022 Current_Project
: Project_Node_Id
;
1023 Packages_To_Check
: String_List_Access
;
1024 Is_Config_File
: Boolean;
1025 Flags
: Processing_Flags
)
1027 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1028 Current_Package
: Package_Node_Id
:= Empty_Package
;
1029 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1030 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1031 Renaming
: Boolean := False;
1032 Extending
: Boolean := False;
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
1154 elsif Token
= Tok_Extends
then
1158 if Renaming
or else Extending
then
1159 if Is_Config_File
then
1162 "no package rename or extension in configuration projects",
1166 -- Scan past "renames" or "extends"
1170 Expect
(Tok_Identifier
, "identifier");
1172 if Token
= Tok_Identifier
then
1174 Project_Name
: constant Name_Id
:= Token_Name
;
1176 Clause
: Project_Node_Id
:=
1177 First_With_Clause_Of
(Current_Project
, In_Tree
);
1178 The_Project
: Project_Node_Id
:= Empty_Node
;
1179 Extended
: constant Project_Node_Id
:=
1181 (Project_Declaration_Of
1182 (Current_Project
, In_Tree
),
1185 while Present
(Clause
) loop
1186 -- Only non limited imported projects may be used in a
1187 -- renames declaration.
1190 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1191 exit when Present
(The_Project
)
1192 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1193 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1197 -- As we have not found the project in the imports, we check
1198 -- if it's the name of an eventual extended project.
1200 if Present
(Extended
)
1201 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1203 Set_Project_Of_Renamed_Package_Of
1204 (Package_Declaration
, In_Tree
, To
=> Extended
);
1206 Error_Msg_Name_1
:= Project_Name
;
1209 "% is not an imported or extended project", Token_Ptr
);
1212 Set_Project_Of_Renamed_Package_Of
1213 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1218 Expect
(Tok_Dot
, "`.`");
1220 if Token
= Tok_Dot
then
1222 Expect
(Tok_Identifier
, "identifier");
1224 if Token
= Tok_Identifier
then
1225 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1226 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1228 Present
(Project_Of_Renamed_Package_Of
1229 (Package_Declaration
, In_Tree
))
1232 Current
: Project_Node_Id
:=
1234 (Project_Of_Renamed_Package_Of
1235 (Package_Declaration
, In_Tree
),
1239 while Present
(Current
)
1240 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1243 Next_Package_In_Project
(Current
, In_Tree
);
1246 if No
(Current
) then
1249 Get_Name_String
(Token_Name
) &
1250 """ is not a package declared by the project",
1263 Expect
(Tok_Semicolon
, "`;`");
1264 Set_End_Of_Line
(Package_Declaration
);
1265 Set_Previous_Line_Node
(Package_Declaration
);
1267 elsif Token
= Tok_Is
then
1268 Set_End_Of_Line
(Package_Declaration
);
1269 Set_Previous_Line_Node
(Package_Declaration
);
1270 Set_Next_End_Node
(Package_Declaration
);
1272 Parse_Declarative_Items
1273 (In_Tree
=> In_Tree
,
1274 Declarations
=> First_Declarative_Item
,
1275 In_Zone
=> In_Package
,
1276 First_Attribute
=> First_Attribute
,
1277 Current_Project
=> Current_Project
,
1278 Current_Package
=> Package_Declaration
,
1279 Packages_To_Check
=> Packages_To_Check
,
1280 Is_Config_File
=> Is_Config_File
,
1283 Set_First_Declarative_Item_Of
1284 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1286 Expect
(Tok_End
, "END");
1288 if Token
= Tok_End
then
1295 -- We should have the name of the package after "end"
1297 Expect
(Tok_Identifier
, "identifier");
1299 if Token
= Tok_Identifier
1300 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1301 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1303 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1304 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1307 if Token
/= Tok_Semicolon
then
1309 -- Scan past the package name
1314 Expect
(Tok_Semicolon
, "`;`");
1315 Remove_Next_End_Node
;
1318 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1321 end Parse_Package_Declaration
;
1323 -----------------------------------
1324 -- Parse_String_Type_Declaration --
1325 -----------------------------------
1327 procedure Parse_String_Type_Declaration
1328 (In_Tree
: Project_Node_Tree_Ref
;
1329 String_Type
: out Project_Node_Id
;
1330 Current_Project
: Project_Node_Id
;
1331 Flags
: Processing_Flags
)
1333 Current
: Project_Node_Id
:= Empty_Node
;
1334 First_String
: Project_Node_Id
:= Empty_Node
;
1338 Default_Project_Node
1339 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1341 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1347 Expect
(Tok_Identifier
, "identifier");
1349 if Token
= Tok_Identifier
then
1350 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1352 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1353 while Present
(Current
)
1355 Name_Of
(Current
, In_Tree
) /= Token_Name
1357 Current
:= Next_String_Type
(Current
, In_Tree
);
1360 if Present
(Current
) then
1362 "duplicate string type name """ &
1363 Get_Name_String
(Token_Name
) &
1367 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1368 while Present
(Current
)
1369 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1371 Current
:= Next_Variable
(Current
, In_Tree
);
1374 if Present
(Current
) then
1377 Get_Name_String
(Token_Name
) &
1378 """ is already a variable name", Token_Ptr
);
1380 Set_Next_String_Type
1381 (String_Type
, In_Tree
,
1382 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1383 Set_First_String_Type_Of
1384 (Current_Project
, In_Tree
, To
=> String_Type
);
1388 -- Scan past the name
1393 Expect
(Tok_Is
, "IS");
1395 if Token
= Tok_Is
then
1399 Expect
(Tok_Left_Paren
, "`(`");
1401 if Token
= Tok_Left_Paren
then
1405 Parse_String_Type_List
1406 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1407 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1409 Expect
(Tok_Right_Paren
, "`)`");
1411 if Token
= Tok_Right_Paren
then
1415 end Parse_String_Type_Declaration
;
1417 --------------------------------
1418 -- Parse_Variable_Declaration --
1419 --------------------------------
1421 procedure Parse_Variable_Declaration
1422 (In_Tree
: Project_Node_Tree_Ref
;
1423 Variable
: out Project_Node_Id
;
1424 Current_Project
: Project_Node_Id
;
1425 Current_Package
: Project_Node_Id
;
1426 Flags
: Processing_Flags
)
1428 Expression_Location
: Source_Ptr
;
1429 String_Type_Name
: Name_Id
:= No_Name
;
1430 Project_String_Type_Name
: Name_Id
:= No_Name
;
1431 Type_Location
: Source_Ptr
:= No_Location
;
1432 Project_Location
: Source_Ptr
:= No_Location
;
1433 Expression
: Project_Node_Id
:= Empty_Node
;
1434 Variable_Name
: constant Name_Id
:= Token_Name
;
1435 OK
: Boolean := True;
1439 Default_Project_Node
1440 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1441 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1442 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1444 -- Scan past the variable name
1448 if Token
= Tok_Colon
then
1450 -- Typed string variable declaration
1453 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1454 Expect
(Tok_Identifier
, "identifier");
1456 OK
:= Token
= Tok_Identifier
;
1459 String_Type_Name
:= Token_Name
;
1460 Type_Location
:= Token_Ptr
;
1463 if Token
= Tok_Dot
then
1464 Project_String_Type_Name
:= String_Type_Name
;
1465 Project_Location
:= Type_Location
;
1467 -- Scan past the dot
1470 Expect
(Tok_Identifier
, "identifier");
1472 if Token
= Tok_Identifier
then
1473 String_Type_Name
:= Token_Name
;
1474 Type_Location
:= Token_Ptr
;
1483 Proj
: Project_Node_Id
:= Current_Project
;
1484 Current
: Project_Node_Id
:= Empty_Node
;
1487 if Project_String_Type_Name
/= No_Name
then
1489 The_Project_Name_And_Node
: constant
1490 Tree_Private_Part
.Project_Name_And_Node
:=
1491 Tree_Private_Part
.Projects_Htable
.Get
1492 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1494 use Tree_Private_Part
;
1497 if The_Project_Name_And_Node
=
1498 Tree_Private_Part
.No_Project_Name_And_Node
1501 "unknown project """ &
1503 (Project_String_Type_Name
) &
1506 Current
:= Empty_Node
;
1509 First_String_Type_Of
1510 (The_Project_Name_And_Node
.Node
, In_Tree
);
1514 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1516 Current
:= Next_String_Type
(Current
, In_Tree
);
1522 -- Look for a string type with the correct name in this
1523 -- project or in any of its ancestors.
1527 First_String_Type_Of
(Proj
, In_Tree
);
1531 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1533 Current
:= Next_String_Type
(Current
, In_Tree
);
1536 exit when Present
(Current
);
1538 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1539 exit when No
(Proj
);
1543 if No
(Current
) then
1545 "unknown string type """ &
1546 Get_Name_String
(String_Type_Name
) &
1553 (Variable
, In_Tree
, To
=> Current
);
1560 Expect
(Tok_Colon_Equal
, "`:=`");
1562 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1564 if Token
= Tok_Colon_Equal
then
1568 -- Get the single string or string list value
1570 Expression_Location
:= Token_Ptr
;
1573 (In_Tree
=> In_Tree
,
1574 Expression
=> Expression
,
1576 Current_Project
=> Current_Project
,
1577 Current_Package
=> Current_Package
,
1578 Optional_Index
=> False);
1579 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1581 if Present
(Expression
) then
1582 -- A typed string must have a single string value, not a list
1584 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1585 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1589 "expression must be a single string", Expression_Location
);
1592 Set_Expression_Kind_Of
1594 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1599 The_Variable
: Project_Node_Id
:= Empty_Node
;
1602 if Present
(Current_Package
) then
1603 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1604 elsif Present
(Current_Project
) then
1605 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1608 while Present
(The_Variable
)
1609 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1611 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1614 if No
(The_Variable
) then
1615 if Present
(Current_Package
) then
1618 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1619 Set_First_Variable_Of
1620 (Current_Package
, In_Tree
, To
=> Variable
);
1622 elsif Present
(Current_Project
) then
1625 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1626 Set_First_Variable_Of
1627 (Current_Project
, In_Tree
, To
=> Variable
);
1631 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1632 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1635 Set_Expression_Kind_Of
1636 (The_Variable
, In_Tree
,
1637 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1640 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1641 Expression_Kind_Of
(Variable
, In_Tree
)
1644 "wrong expression kind for variable """ &
1646 (Name_Of
(The_Variable
, In_Tree
)) &
1648 Expression_Location
);
1655 end Parse_Variable_Declaration
;