1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2014, 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 Prj
.Attr
; use Prj
.Attr
;
29 with Prj
.Attr
.PM
; use Prj
.Attr
.PM
;
30 with Prj
.Err
; use Prj
.Err
;
31 with Prj
.Strt
; use Prj
.Strt
;
32 with Prj
.Tree
; use Prj
.Tree
;
34 with Uintp
; use Uintp
;
37 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
38 with GNAT
.Spelling_Checker
; use GNAT
.Spelling_Checker
;
41 package body Prj
.Dect
is
43 type Zone
is (In_Project
, In_Package
, In_Case_Construction
);
44 -- Used to indicate if we are parsing a package (In_Package), a case
45 -- construction (In_Case_Construction) or none of those two (In_Project).
47 procedure Rename_Obsolescent_Attributes
48 (In_Tree
: Project_Node_Tree_Ref
;
49 Attribute
: Project_Node_Id
;
50 Current_Package
: Project_Node_Id
);
51 -- Rename obsolescent attributes in the tree. When the attribute has been
52 -- renamed since its initial introduction in the design of projects, we
53 -- replace the old name in the tree with the new name, so that the code
54 -- does not have to check both names forever.
56 procedure Check_Attribute_Allowed
57 (In_Tree
: Project_Node_Tree_Ref
;
58 Project
: Project_Node_Id
;
59 Attribute
: Project_Node_Id
;
60 Flags
: Processing_Flags
);
61 -- Check whether the attribute is valid in this project. In particular,
62 -- depending on the type of project (qualifier), some attributes might
65 procedure Check_Package_Allowed
66 (In_Tree
: Project_Node_Tree_Ref
;
67 Project
: Project_Node_Id
;
68 Current_Package
: Project_Node_Id
;
69 Flags
: Processing_Flags
);
70 -- Check whether the package is valid in this project
72 procedure Parse_Attribute_Declaration
73 (In_Tree
: Project_Node_Tree_Ref
;
74 Attribute
: out Project_Node_Id
;
75 First_Attribute
: Attribute_Node_Id
;
76 Current_Project
: Project_Node_Id
;
77 Current_Package
: Project_Node_Id
;
78 Packages_To_Check
: String_List_Access
;
79 Flags
: Processing_Flags
);
80 -- Parse an attribute declaration
82 procedure Parse_Case_Construction
83 (In_Tree
: Project_Node_Tree_Ref
;
84 Case_Construction
: out Project_Node_Id
;
85 First_Attribute
: Attribute_Node_Id
;
86 Current_Project
: Project_Node_Id
;
87 Current_Package
: Project_Node_Id
;
88 Packages_To_Check
: String_List_Access
;
89 Is_Config_File
: Boolean;
90 Flags
: Processing_Flags
);
91 -- Parse a case construction
93 procedure Parse_Declarative_Items
94 (In_Tree
: Project_Node_Tree_Ref
;
95 Declarations
: out Project_Node_Id
;
97 First_Attribute
: Attribute_Node_Id
;
98 Current_Project
: Project_Node_Id
;
99 Current_Package
: Project_Node_Id
;
100 Packages_To_Check
: String_List_Access
;
101 Is_Config_File
: Boolean;
102 Flags
: Processing_Flags
);
103 -- Parse declarative items. Depending on In_Zone, some declarative items
104 -- may be forbidden. Is_Config_File should be set to True if the project
105 -- represents a config file (.cgpr) since some specific checks apply.
107 procedure Parse_Package_Declaration
108 (In_Tree
: Project_Node_Tree_Ref
;
109 Package_Declaration
: out Project_Node_Id
;
110 Current_Project
: Project_Node_Id
;
111 Packages_To_Check
: String_List_Access
;
112 Is_Config_File
: Boolean;
113 Flags
: Processing_Flags
);
114 -- Parse a package declaration.
115 -- Is_Config_File should be set to True if the project represents a config
116 -- file (.cgpr) since some specific checks apply.
118 procedure Parse_String_Type_Declaration
119 (In_Tree
: Project_Node_Tree_Ref
;
120 String_Type
: out Project_Node_Id
;
121 Current_Project
: Project_Node_Id
;
122 Flags
: Processing_Flags
);
123 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
125 procedure Parse_Variable_Declaration
126 (In_Tree
: Project_Node_Tree_Ref
;
127 Variable
: out Project_Node_Id
;
128 Current_Project
: Project_Node_Id
;
129 Current_Package
: Project_Node_Id
;
130 Flags
: Processing_Flags
);
131 -- Parse a variable assignment
132 -- <variable_Name> := <expression>; OR
133 -- <variable_Name> : <string_type_Name> := <string_expression>;
140 (In_Tree
: Project_Node_Tree_Ref
;
141 Declarations
: out Project_Node_Id
;
142 Current_Project
: Project_Node_Id
;
143 Extends
: Project_Node_Id
;
144 Packages_To_Check
: String_List_Access
;
145 Is_Config_File
: Boolean;
146 Flags
: Processing_Flags
)
148 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
153 (Of_Kind
=> N_Project_Declaration
, In_Tree
=> In_Tree
);
154 Set_Location_Of
(Declarations
, In_Tree
, To
=> Token_Ptr
);
155 Set_Extended_Project_Of
(Declarations
, In_Tree
, To
=> Extends
);
156 Set_Project_Declaration_Of
(Current_Project
, In_Tree
, Declarations
);
157 Parse_Declarative_Items
158 (Declarations
=> First_Declarative_Item
,
160 In_Zone
=> In_Project
,
161 First_Attribute
=> Prj
.Attr
.Attribute_First
,
162 Current_Project
=> Current_Project
,
163 Current_Package
=> Empty_Node
,
164 Packages_To_Check
=> Packages_To_Check
,
165 Is_Config_File
=> Is_Config_File
,
167 Set_First_Declarative_Item_Of
168 (Declarations
, In_Tree
, To
=> First_Declarative_Item
);
171 -----------------------------------
172 -- Rename_Obsolescent_Attributes --
173 -----------------------------------
175 procedure Rename_Obsolescent_Attributes
176 (In_Tree
: Project_Node_Tree_Ref
;
177 Attribute
: Project_Node_Id
;
178 Current_Package
: Project_Node_Id
)
181 if Present
(Current_Package
)
182 and then Expression_Kind_Of
(Current_Package
, In_Tree
) /= Ignored
184 case Name_Of
(Attribute
, In_Tree
) is
185 when Snames
.Name_Specification
=>
186 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec
);
188 when Snames
.Name_Specification_Suffix
=>
189 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec_Suffix
);
191 when Snames
.Name_Implementation
=>
192 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body
);
194 when Snames
.Name_Implementation_Suffix
=>
195 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body_Suffix
);
201 end Rename_Obsolescent_Attributes
;
203 ---------------------------
204 -- Check_Package_Allowed --
205 ---------------------------
207 procedure Check_Package_Allowed
208 (In_Tree
: Project_Node_Tree_Ref
;
209 Project
: Project_Node_Id
;
210 Current_Package
: Project_Node_Id
;
211 Flags
: Processing_Flags
)
213 Qualif
: constant Project_Qualifier
:=
214 Project_Qualifier_Of
(Project
, In_Tree
);
215 Name
: constant Name_Id
:= Name_Of
(Current_Package
, In_Tree
);
217 if (Qualif
= Aggregate
and then Name
/= Snames
.Name_Builder
)
218 or else (Qualif
= Aggregate_Library
219 and then Name
/= Snames
.Name_Builder
220 and then Name
/= Snames
.Name_Install
)
222 Error_Msg_Name_1
:= Name
;
225 "package %% is forbidden in aggregate projects",
226 Location_Of
(Current_Package
, In_Tree
));
228 end Check_Package_Allowed
;
230 -----------------------------
231 -- Check_Attribute_Allowed --
232 -----------------------------
234 procedure Check_Attribute_Allowed
235 (In_Tree
: Project_Node_Tree_Ref
;
236 Project
: Project_Node_Id
;
237 Attribute
: Project_Node_Id
;
238 Flags
: Processing_Flags
)
240 Qualif
: constant Project_Qualifier
:=
241 Project_Qualifier_Of
(Project
, In_Tree
);
242 Name
: constant Name_Id
:= Name_Of
(Attribute
, In_Tree
);
246 when Aggregate | Aggregate_Library
=>
247 if Name
= Snames
.Name_Languages
248 or else Name
= Snames
.Name_Source_Files
249 or else Name
= Snames
.Name_Source_List_File
250 or else Name
= Snames
.Name_Locally_Removed_Files
251 or else Name
= Snames
.Name_Excluded_Source_Files
252 or else Name
= Snames
.Name_Excluded_Source_List_File
253 or else Name
= Snames
.Name_Interfaces
254 or else Name
= Snames
.Name_Object_Dir
255 or else Name
= Snames
.Name_Exec_Dir
256 or else Name
= Snames
.Name_Source_Dirs
257 or else Name
= Snames
.Name_Inherit_Source_Path
259 (Qualif
= Aggregate
and then Name
= Snames
.Name_Library_Dir
)
261 (Qualif
= Aggregate
and then Name
= Snames
.Name_Library_Name
)
262 or else Name
= Snames
.Name_Main
263 or else Name
= Snames
.Name_Roots
264 or else Name
= Snames
.Name_Externally_Built
265 or else Name
= Snames
.Name_Executable
266 or else Name
= Snames
.Name_Executable_Suffix
267 or else Name
= Snames
.Name_Default_Switches
269 Error_Msg_Name_1
:= Name
;
272 "%% is not valid in aggregate projects",
273 Location_Of
(Attribute
, In_Tree
));
277 if Name
= Snames
.Name_Project_Files
278 or else Name
= Snames
.Name_Project_Path
279 or else Name
= Snames
.Name_External
281 Error_Msg_Name_1
:= Name
;
284 "%% is only valid in aggregate projects",
285 Location_Of
(Attribute
, In_Tree
));
288 end Check_Attribute_Allowed
;
290 ---------------------------------
291 -- Parse_Attribute_Declaration --
292 ---------------------------------
294 procedure Parse_Attribute_Declaration
295 (In_Tree
: Project_Node_Tree_Ref
;
296 Attribute
: out Project_Node_Id
;
297 First_Attribute
: Attribute_Node_Id
;
298 Current_Project
: Project_Node_Id
;
299 Current_Package
: Project_Node_Id
;
300 Packages_To_Check
: String_List_Access
;
301 Flags
: Processing_Flags
)
303 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
304 Full_Associative_Array
: Boolean := False;
305 Attribute_Name
: Name_Id
:= No_Name
;
306 Optional_Index
: Boolean := False;
307 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
309 procedure Process_Attribute_Name
;
310 -- Read the name of the attribute, and check its type
312 procedure Process_Associative_Array_Index
;
313 -- Read the index of the associative array and check its validity
315 ----------------------------
316 -- Process_Attribute_Name --
317 ----------------------------
319 procedure Process_Attribute_Name
is
323 Attribute_Name
:= Token_Name
;
324 Set_Name_Of
(Attribute
, In_Tree
, To
=> Attribute_Name
);
325 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
327 -- Find the attribute
330 Attribute_Node_Id_Of
(Attribute_Name
, First_Attribute
);
332 -- If the attribute cannot be found, create the attribute if inside
333 -- an unknown package.
335 if Current_Attribute
= Empty_Attribute
then
336 if Present
(Current_Package
)
337 and then Expression_Kind_Of
(Current_Package
, In_Tree
) = Ignored
339 Pkg_Id
:= Package_Id_Of
(Current_Package
, In_Tree
);
340 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
343 -- If not a valid attribute name, issue an error if inside
344 -- a package that need to be checked.
346 Ignore
:= Present
(Current_Package
) and then
347 Packages_To_Check
/= All_Packages
;
351 -- Check that we are not in a package to check
353 Get_Name_String
(Name_Of
(Current_Package
, In_Tree
));
355 for Index
in Packages_To_Check
'Range loop
356 if Name_Buffer
(1 .. Name_Len
) =
357 Packages_To_Check
(Index
).all
366 Error_Msg_Name_1
:= Token_Name
;
367 Error_Msg
(Flags
, "undefined attribute %%", Token_Ptr
);
371 -- Set, if appropriate the index case insensitivity flag
374 if Is_Read_Only
(Current_Attribute
) then
375 Error_Msg_Name_1
:= Token_Name
;
377 (Flags
, "read-only attribute %% cannot be given a value",
381 if Attribute_Kind_Of
(Current_Attribute
) in
382 All_Case_Insensitive_Associative_Array
384 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
388 Scan
(In_Tree
); -- past the attribute name
390 -- Set the expression kind of the attribute
392 if Current_Attribute
/= Empty_Attribute
then
393 Set_Expression_Kind_Of
394 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
395 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
397 end Process_Attribute_Name
;
399 -------------------------------------
400 -- Process_Associative_Array_Index --
401 -------------------------------------
403 procedure Process_Associative_Array_Index
is
405 -- If the attribute is not an associative array attribute, report
406 -- an error. If this information is still unknown, set the kind
407 -- to Associative_Array.
409 if Current_Attribute
/= Empty_Attribute
410 and then Attribute_Kind_Of
(Current_Attribute
) = Single
414 Get_Name_String
(Attribute_Name_Of
(Current_Attribute
))
415 & """ cannot be an associative array",
416 Location_Of
(Attribute
, In_Tree
));
418 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
419 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
422 Scan
(In_Tree
); -- past the left parenthesis
424 if Others_Allowed_For
(Current_Attribute
)
425 and then Token
= Tok_Others
427 Set_Associative_Array_Index_Of
428 (Attribute
, In_Tree
, All_Other_Names
);
429 Scan
(In_Tree
); -- past others
432 if Others_Allowed_For
(Current_Attribute
) then
433 Expect
(Tok_String_Literal
, "literal string or others");
435 Expect
(Tok_String_Literal
, "literal string");
438 if Token
= Tok_String_Literal
then
439 Get_Name_String
(Token_Name
);
441 if Case_Insensitive
(Attribute
, In_Tree
) then
442 To_Lower
(Name_Buffer
(1 .. Name_Len
));
445 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
446 Scan
(In_Tree
); -- past the literal string index
448 if Token
= Tok_At
then
449 case Attribute_Kind_Of
(Current_Attribute
) is
450 when Optional_Index_Associative_Array |
451 Optional_Index_Case_Insensitive_Associative_Array
=>
453 Expect
(Tok_Integer_Literal
, "integer literal");
455 if Token
= Tok_Integer_Literal
then
457 -- Set the source index value from given literal
460 Index
: constant Int
:=
461 UI_To_Int
(Int_Literal_Value
);
465 (Flags
, "index cannot be zero", Token_Ptr
);
468 (Attribute
, In_Tree
, To
=> Index
);
476 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
479 if Token
= Tok_Integer_Literal
then
487 Expect
(Tok_Right_Paren
, "`)`");
489 if Token
= Tok_Right_Paren
then
490 Scan
(In_Tree
); -- past the right parenthesis
492 end Process_Associative_Array_Index
;
497 (Of_Kind
=> N_Attribute_Declaration
, In_Tree
=> In_Tree
);
498 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
499 Set_Previous_Line_Node
(Attribute
);
505 -- Body or External may be an attribute name
507 if Token
= Tok_Body
then
508 Token
:= Tok_Identifier
;
509 Token_Name
:= Snames
.Name_Body
;
512 if Token
= Tok_External
then
513 Token
:= Tok_Identifier
;
514 Token_Name
:= Snames
.Name_External
;
517 Expect
(Tok_Identifier
, "identifier");
518 Process_Attribute_Name
;
519 Rename_Obsolescent_Attributes
(In_Tree
, Attribute
, Current_Package
);
520 Check_Attribute_Allowed
(In_Tree
, Current_Project
, Attribute
, Flags
);
522 -- Associative array attributes
524 if Token
= Tok_Left_Paren
then
525 Process_Associative_Array_Index
;
528 -- If it is an associative array attribute and there are no left
529 -- parenthesis, then this is a full associative array declaration.
530 -- Flag it as such for later processing of its value.
532 if Current_Attribute
/= Empty_Attribute
534 Attribute_Kind_Of
(Current_Attribute
) /= Single
536 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
537 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
540 Full_Associative_Array
:= True;
545 Expect
(Tok_Use
, "USE");
547 if Token
= Tok_Use
then
550 if Full_Associative_Array
then
552 -- Expect <project>'<same_attribute_name>, or
553 -- <project>.<same_package_name>'<same_attribute_name>
556 The_Project
: Project_Node_Id
:= Empty_Node
;
557 -- The node of the project where the associative array is
560 The_Package
: Project_Node_Id
:= Empty_Node
;
561 -- The node of the package where the associative array is
564 Project_Name
: Name_Id
:= No_Name
;
565 -- The name of the project where the associative array is
568 Location
: Source_Ptr
:= No_Location
;
569 -- The location of the project name
572 Expect
(Tok_Identifier
, "identifier");
574 if Token
= Tok_Identifier
then
575 Location
:= Token_Ptr
;
577 -- Find the project node in the imported project or
578 -- in the project being extended.
580 The_Project
:= Imported_Or_Extended_Project_Of
581 (Current_Project
, In_Tree
, Token_Name
);
583 if No
(The_Project
) then
584 Error_Msg
(Flags
, "unknown project", Location
);
585 Scan
(In_Tree
); -- past the project name
588 Project_Name
:= Token_Name
;
589 Scan
(In_Tree
); -- past the project name
591 -- If this is inside a package, a dot followed by the
592 -- name of the package must followed the project name.
594 if Present
(Current_Package
) then
595 Expect
(Tok_Dot
, "`.`");
597 if Token
/= Tok_Dot
then
598 The_Project
:= Empty_Node
;
601 Scan
(In_Tree
); -- past the dot
602 Expect
(Tok_Identifier
, "identifier");
604 if Token
/= Tok_Identifier
then
605 The_Project
:= Empty_Node
;
607 -- If it is not the same package name, issue error
610 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
612 The_Project
:= Empty_Node
;
614 (Flags
, "not the same package as " &
616 (Name_Of
(Current_Package
, In_Tree
)),
621 First_Package_Of
(The_Project
, In_Tree
);
623 -- Look for the package node
625 while Present
(The_Package
)
627 Name_Of
(The_Package
, In_Tree
) /= Token_Name
630 Next_Package_In_Project
631 (The_Package
, In_Tree
);
634 -- If the package cannot be found in the
635 -- project, issue an error.
637 if No
(The_Package
) then
638 The_Project
:= Empty_Node
;
639 Error_Msg_Name_2
:= Project_Name
;
640 Error_Msg_Name_1
:= Token_Name
;
643 "package % not declared in project %",
647 Scan
(In_Tree
); -- past the package name
654 if Present
(The_Project
) then
656 -- Looking for '<same attribute name>
658 Expect
(Tok_Apostrophe
, "`''`");
660 if Token
/= Tok_Apostrophe
then
661 The_Project
:= Empty_Node
;
664 Scan
(In_Tree
); -- past the apostrophe
665 Expect
(Tok_Identifier
, "identifier");
667 if Token
/= Tok_Identifier
then
668 The_Project
:= Empty_Node
;
671 -- If it is not the same attribute name, issue error
673 if Token_Name
/= Attribute_Name
then
674 The_Project
:= Empty_Node
;
675 Error_Msg_Name_1
:= Attribute_Name
;
677 (Flags
, "invalid name, should be %", Token_Ptr
);
680 Scan
(In_Tree
); -- past the attribute name
685 if No
(The_Project
) then
687 -- If there were any problem, set the attribute id to null,
688 -- so that the node will not be recorded.
690 Current_Attribute
:= Empty_Attribute
;
693 -- Set the appropriate field in the node.
694 -- Note that the index and the expression are nil. This
695 -- characterizes full associative array attribute
698 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
699 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
703 -- Other attribute declarations (not full associative array)
707 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
708 -- The location of the first token of the expression
710 Expression
: Project_Node_Id
:= Empty_Node
;
711 -- The expression, value for the attribute declaration
714 -- Get the expression value and set it in the attribute node
718 Expression
=> Expression
,
720 Current_Project
=> Current_Project
,
721 Current_Package
=> Current_Package
,
722 Optional_Index
=> Optional_Index
);
723 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
725 -- If the expression is legal, but not of the right kind
726 -- for the attribute, issue an error.
728 if Current_Attribute
/= Empty_Attribute
729 and then Present
(Expression
)
730 and then Variable_Kind_Of
(Current_Attribute
) /=
731 Expression_Kind_Of
(Expression
, In_Tree
)
733 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
736 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
740 (Flags
, "wrong expression kind for attribute """ &
742 (Attribute_Name_Of
(Current_Attribute
)) &
744 Expression_Location
);
751 -- If the attribute was not recognized, return an empty node.
752 -- It may be that it is not in a package to check, and the node will
753 -- not be added to the tree.
755 if Current_Attribute
= Empty_Attribute
then
756 Attribute
:= Empty_Node
;
759 Set_End_Of_Line
(Attribute
);
760 Set_Previous_Line_Node
(Attribute
);
761 end Parse_Attribute_Declaration
;
763 -----------------------------
764 -- Parse_Case_Construction --
765 -----------------------------
767 procedure Parse_Case_Construction
768 (In_Tree
: Project_Node_Tree_Ref
;
769 Case_Construction
: out Project_Node_Id
;
770 First_Attribute
: Attribute_Node_Id
;
771 Current_Project
: Project_Node_Id
;
772 Current_Package
: Project_Node_Id
;
773 Packages_To_Check
: String_List_Access
;
774 Is_Config_File
: Boolean;
775 Flags
: Processing_Flags
)
777 Current_Item
: Project_Node_Id
:= Empty_Node
;
778 Next_Item
: Project_Node_Id
:= Empty_Node
;
779 First_Case_Item
: Boolean := True;
781 Variable_Location
: Source_Ptr
:= No_Location
;
783 String_Type
: Project_Node_Id
:= Empty_Node
;
785 Case_Variable
: Project_Node_Id
:= Empty_Node
;
787 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
789 First_Choice
: Project_Node_Id
:= Empty_Node
;
791 When_Others
: Boolean := False;
792 -- Set to True when there is a "when others =>" clause
797 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
798 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
804 -- Get the switch variable
806 Expect
(Tok_Identifier
, "identifier");
808 if Token
= Tok_Identifier
then
809 Variable_Location
:= Token_Ptr
;
810 Parse_Variable_Reference
812 Variable
=> Case_Variable
,
814 Current_Project
=> Current_Project
,
815 Current_Package
=> Current_Package
);
816 Set_Case_Variable_Reference_Of
817 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
820 if Token
/= Tok_Is
then
825 if Present
(Case_Variable
) then
826 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
828 if No
(String_Type
) then
831 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
837 Expect
(Tok_Is
, "IS");
839 if Token
= Tok_Is
then
840 Set_End_Of_Line
(Case_Construction
);
841 Set_Previous_Line_Node
(Case_Construction
);
842 Set_Next_End_Node
(Case_Construction
);
849 Start_New_Case_Construction
(In_Tree
, String_Type
);
853 while Token
= Tok_When
loop
855 if First_Case_Item
then
858 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
859 Set_First_Case_Item_Of
860 (Case_Construction
, In_Tree
, To
=> Current_Item
);
861 First_Case_Item
:= False;
866 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
867 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
868 Current_Item
:= Next_Item
;
871 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
877 if Token
= Tok_Others
then
880 -- Scan past "others"
884 Expect
(Tok_Arrow
, "`=>`");
885 Set_End_Of_Line
(Current_Item
);
886 Set_Previous_Line_Node
(Current_Item
);
888 -- Empty_Node in Field1 of a Case_Item indicates
889 -- the "when others =>" branch.
891 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
893 Parse_Declarative_Items
895 Declarations
=> First_Declarative_Item
,
896 In_Zone
=> In_Case_Construction
,
897 First_Attribute
=> First_Attribute
,
898 Current_Project
=> Current_Project
,
899 Current_Package
=> Current_Package
,
900 Packages_To_Check
=> Packages_To_Check
,
901 Is_Config_File
=> Is_Config_File
,
904 -- "when others =>" must be the last branch, so save the
905 -- Case_Item and exit
907 Set_First_Declarative_Item_Of
908 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
914 First_Choice
=> First_Choice
,
916 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
918 Expect
(Tok_Arrow
, "`=>`");
919 Set_End_Of_Line
(Current_Item
);
920 Set_Previous_Line_Node
(Current_Item
);
922 Parse_Declarative_Items
924 Declarations
=> First_Declarative_Item
,
925 In_Zone
=> In_Case_Construction
,
926 First_Attribute
=> First_Attribute
,
927 Current_Project
=> Current_Project
,
928 Current_Package
=> Current_Package
,
929 Packages_To_Check
=> Packages_To_Check
,
930 Is_Config_File
=> Is_Config_File
,
933 Set_First_Declarative_Item_Of
934 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
939 End_Case_Construction
940 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
941 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
944 Expect
(Tok_End
, "`END CASE`");
945 Remove_Next_End_Node
;
947 if Token
= Tok_End
then
953 Expect
(Tok_Case
, "CASE");
961 Expect
(Tok_Semicolon
, "`;`");
962 Set_Previous_End_Node
(Case_Construction
);
964 end Parse_Case_Construction
;
966 -----------------------------
967 -- Parse_Declarative_Items --
968 -----------------------------
970 procedure Parse_Declarative_Items
971 (In_Tree
: Project_Node_Tree_Ref
;
972 Declarations
: out Project_Node_Id
;
974 First_Attribute
: Attribute_Node_Id
;
975 Current_Project
: Project_Node_Id
;
976 Current_Package
: Project_Node_Id
;
977 Packages_To_Check
: String_List_Access
;
978 Is_Config_File
: Boolean;
979 Flags
: Processing_Flags
)
981 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
982 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
983 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
984 Item_Location
: Source_Ptr
:= No_Location
;
987 Declarations
:= Empty_Node
;
990 -- We are always positioned at the token that precedes the first
991 -- token of the declarative element. Scan past it.
995 Item_Location
:= Token_Ptr
;
998 when Tok_Identifier
=>
1000 if In_Zone
= In_Case_Construction
then
1002 -- Check if the variable has already been declared
1005 The_Variable
: Project_Node_Id
:= Empty_Node
;
1008 if Present
(Current_Package
) then
1010 First_Variable_Of
(Current_Package
, In_Tree
);
1011 elsif Present
(Current_Project
) then
1013 First_Variable_Of
(Current_Project
, In_Tree
);
1016 while Present
(The_Variable
)
1017 and then Name_Of
(The_Variable
, In_Tree
) /=
1020 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1023 -- It is an error to declare a variable in a case
1024 -- construction for the first time.
1026 if No
(The_Variable
) then
1029 "a variable cannot be declared " &
1030 "for the first time here",
1036 Parse_Variable_Declaration
1038 Current_Declaration
,
1039 Current_Project
=> Current_Project
,
1040 Current_Package
=> Current_Package
,
1043 Set_End_Of_Line
(Current_Declaration
);
1044 Set_Previous_Line_Node
(Current_Declaration
);
1048 Parse_Attribute_Declaration
1049 (In_Tree
=> In_Tree
,
1050 Attribute
=> Current_Declaration
,
1051 First_Attribute
=> First_Attribute
,
1052 Current_Project
=> Current_Project
,
1053 Current_Package
=> Current_Package
,
1054 Packages_To_Check
=> Packages_To_Check
,
1057 Set_End_Of_Line
(Current_Declaration
);
1058 Set_Previous_Line_Node
(Current_Declaration
);
1062 Scan
(In_Tree
); -- past "null"
1066 -- Package declaration
1068 if In_Zone
/= In_Project
then
1070 (Flags
, "a package cannot be declared here", Token_Ptr
);
1073 Parse_Package_Declaration
1074 (In_Tree
=> In_Tree
,
1075 Package_Declaration
=> Current_Declaration
,
1076 Current_Project
=> Current_Project
,
1077 Packages_To_Check
=> Packages_To_Check
,
1078 Is_Config_File
=> Is_Config_File
,
1081 Set_Previous_End_Node
(Current_Declaration
);
1085 -- Type String Declaration
1087 if In_Zone
/= In_Project
then
1089 "a string type cannot be declared here",
1093 Parse_String_Type_Declaration
1094 (In_Tree
=> In_Tree
,
1095 String_Type
=> Current_Declaration
,
1096 Current_Project
=> Current_Project
,
1099 Set_End_Of_Line
(Current_Declaration
);
1100 Set_Previous_Line_Node
(Current_Declaration
);
1104 -- Case construction
1106 Parse_Case_Construction
1107 (In_Tree
=> In_Tree
,
1108 Case_Construction
=> Current_Declaration
,
1109 First_Attribute
=> First_Attribute
,
1110 Current_Project
=> Current_Project
,
1111 Current_Package
=> Current_Package
,
1112 Packages_To_Check
=> Packages_To_Check
,
1113 Is_Config_File
=> Is_Config_File
,
1116 Set_Previous_End_Node
(Current_Declaration
);
1121 -- We are leaving Parse_Declarative_Items positioned
1122 -- at the first token after the list of declarative items.
1123 -- It could be "end" (for a project, a package declaration or
1124 -- a case construction) or "when" (for a case construction)
1128 Expect
(Tok_Semicolon
, "`;` after declarative items");
1130 -- Insert an N_Declarative_Item in the tree, but only if
1131 -- Current_Declaration is not an empty node.
1133 if Present
(Current_Declaration
) then
1134 if No
(Current_Declarative_Item
) then
1135 Current_Declarative_Item
:=
1136 Default_Project_Node
1137 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1138 Declarations
:= Current_Declarative_Item
;
1141 Next_Declarative_Item
:=
1142 Default_Project_Node
1143 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1144 Set_Next_Declarative_Item
1145 (Current_Declarative_Item
, In_Tree
,
1146 To
=> Next_Declarative_Item
);
1147 Current_Declarative_Item
:= Next_Declarative_Item
;
1150 Set_Current_Item_Node
1151 (Current_Declarative_Item
, In_Tree
,
1152 To
=> Current_Declaration
);
1154 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1157 end Parse_Declarative_Items
;
1159 -------------------------------
1160 -- Parse_Package_Declaration --
1161 -------------------------------
1163 procedure Parse_Package_Declaration
1164 (In_Tree
: Project_Node_Tree_Ref
;
1165 Package_Declaration
: out Project_Node_Id
;
1166 Current_Project
: Project_Node_Id
;
1167 Packages_To_Check
: String_List_Access
;
1168 Is_Config_File
: Boolean;
1169 Flags
: Processing_Flags
)
1171 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1172 Current_Package
: Package_Node_Id
:= Empty_Package
;
1173 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1174 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1175 Renaming
: Boolean := False;
1176 Extending
: Boolean := False;
1179 Package_Declaration
:=
1180 Default_Project_Node
1181 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1182 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1184 -- Scan past "package"
1187 Expect
(Tok_Identifier
, "identifier");
1189 if Token
= Tok_Identifier
then
1190 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1192 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1194 if Current_Package
= Empty_Package
then
1195 if not Quiet_Output
then
1197 List
: constant Strings
.String_List
:= Package_Name_List
;
1199 Name
: constant String := Get_Name_String
(Token_Name
);
1202 -- Check for possible misspelling of a known package name
1206 if Index
>= List
'Last then
1213 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1214 (Name
, List
(Index
).all);
1217 -- Issue warning(s) in verbose mode or when a possible
1218 -- misspelling has been found.
1220 if Verbose_Mode
or else Index
/= 0 then
1224 (Name_Of
(Package_Declaration
, In_Tree
)) &
1225 """ is not a known package name",
1230 Error_Msg
-- CODEFIX
1232 "\?possible misspelling of """ &
1233 List
(Index
).all & """", Token_Ptr
);
1238 -- Set the package declaration to "ignored" so that it is not
1239 -- processed by Prj.Proc.Process.
1241 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1243 -- Add the unknown package in the list of packages
1245 Add_Unknown_Package
(Token_Name
, Current_Package
);
1247 elsif Current_Package
= Unknown_Package
then
1249 -- Set the package declaration to "ignored" so that it is not
1250 -- processed by Prj.Proc.Process.
1252 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1255 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1259 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1262 Current
: Project_Node_Id
:=
1263 First_Package_Of
(Current_Project
, In_Tree
);
1266 while Present
(Current
)
1267 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1269 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1272 if Present
(Current
) then
1276 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1277 """ is declared twice in the same project",
1281 -- Add the package to the project list
1283 Set_Next_Package_In_Project
1284 (Package_Declaration
, In_Tree
,
1285 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1286 Set_First_Package_Of
1287 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1291 -- Scan past the package name
1296 Check_Package_Allowed
1297 (In_Tree
, Current_Project
, Package_Declaration
, Flags
);
1299 if Token
= Tok_Renames
then
1301 elsif Token
= Tok_Extends
then
1305 if Renaming
or else Extending
then
1306 if Is_Config_File
then
1309 "no package rename or extension in configuration projects",
1313 -- Scan past "renames" or "extends"
1317 Expect
(Tok_Identifier
, "identifier");
1319 if Token
= Tok_Identifier
then
1321 Project_Name
: constant Name_Id
:= Token_Name
;
1323 Clause
: Project_Node_Id
:=
1324 First_With_Clause_Of
(Current_Project
, In_Tree
);
1325 The_Project
: Project_Node_Id
:= Empty_Node
;
1326 Extended
: constant Project_Node_Id
:=
1328 (Project_Declaration_Of
1329 (Current_Project
, In_Tree
),
1332 while Present
(Clause
) loop
1333 -- Only non limited imported projects may be used in a
1334 -- renames declaration.
1337 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1338 exit when Present
(The_Project
)
1339 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1340 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1344 -- As we have not found the project in the imports, we check
1345 -- if it's the name of an eventual extended project.
1347 if Present
(Extended
)
1348 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1350 Set_Project_Of_Renamed_Package_Of
1351 (Package_Declaration
, In_Tree
, To
=> Extended
);
1353 Error_Msg_Name_1
:= Project_Name
;
1356 "% is not an imported or extended project", Token_Ptr
);
1359 Set_Project_Of_Renamed_Package_Of
1360 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1365 Expect
(Tok_Dot
, "`.`");
1367 if Token
= Tok_Dot
then
1369 Expect
(Tok_Identifier
, "identifier");
1371 if Token
= Tok_Identifier
then
1372 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1373 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1375 Present
(Project_Of_Renamed_Package_Of
1376 (Package_Declaration
, In_Tree
))
1379 Current
: Project_Node_Id
:=
1381 (Project_Of_Renamed_Package_Of
1382 (Package_Declaration
, In_Tree
),
1386 while Present
(Current
)
1387 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1390 Next_Package_In_Project
(Current
, In_Tree
);
1393 if No
(Current
) then
1396 Get_Name_String
(Token_Name
) &
1397 """ is not a package declared by the project",
1410 Expect
(Tok_Semicolon
, "`;`");
1411 Set_End_Of_Line
(Package_Declaration
);
1412 Set_Previous_Line_Node
(Package_Declaration
);
1414 elsif Token
= Tok_Is
then
1415 Set_End_Of_Line
(Package_Declaration
);
1416 Set_Previous_Line_Node
(Package_Declaration
);
1417 Set_Next_End_Node
(Package_Declaration
);
1419 Parse_Declarative_Items
1420 (In_Tree
=> In_Tree
,
1421 Declarations
=> First_Declarative_Item
,
1422 In_Zone
=> In_Package
,
1423 First_Attribute
=> First_Attribute
,
1424 Current_Project
=> Current_Project
,
1425 Current_Package
=> Package_Declaration
,
1426 Packages_To_Check
=> Packages_To_Check
,
1427 Is_Config_File
=> Is_Config_File
,
1430 Set_First_Declarative_Item_Of
1431 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1433 Expect
(Tok_End
, "END");
1435 if Token
= Tok_End
then
1442 -- We should have the name of the package after "end"
1444 Expect
(Tok_Identifier
, "identifier");
1446 if Token
= Tok_Identifier
1447 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1448 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1450 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1451 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1454 if Token
/= Tok_Semicolon
then
1456 -- Scan past the package name
1461 Expect
(Tok_Semicolon
, "`;`");
1462 Remove_Next_End_Node
;
1465 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1468 end Parse_Package_Declaration
;
1470 -----------------------------------
1471 -- Parse_String_Type_Declaration --
1472 -----------------------------------
1474 procedure Parse_String_Type_Declaration
1475 (In_Tree
: Project_Node_Tree_Ref
;
1476 String_Type
: out Project_Node_Id
;
1477 Current_Project
: Project_Node_Id
;
1478 Flags
: Processing_Flags
)
1480 Current
: Project_Node_Id
:= Empty_Node
;
1481 First_String
: Project_Node_Id
:= Empty_Node
;
1485 Default_Project_Node
1486 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1488 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1494 Expect
(Tok_Identifier
, "identifier");
1496 if Token
= Tok_Identifier
then
1497 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1499 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1500 while Present
(Current
)
1502 Name_Of
(Current
, In_Tree
) /= Token_Name
1504 Current
:= Next_String_Type
(Current
, In_Tree
);
1507 if Present
(Current
) then
1509 "duplicate string type name """ &
1510 Get_Name_String
(Token_Name
) &
1514 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1515 while Present
(Current
)
1516 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1518 Current
:= Next_Variable
(Current
, In_Tree
);
1521 if Present
(Current
) then
1524 Get_Name_String
(Token_Name
) &
1525 """ is already a variable name", Token_Ptr
);
1527 Set_Next_String_Type
1528 (String_Type
, In_Tree
,
1529 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1530 Set_First_String_Type_Of
1531 (Current_Project
, In_Tree
, To
=> String_Type
);
1535 -- Scan past the name
1540 Expect
(Tok_Is
, "IS");
1542 if Token
= Tok_Is
then
1546 Expect
(Tok_Left_Paren
, "`(`");
1548 if Token
= Tok_Left_Paren
then
1552 Parse_String_Type_List
1553 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1554 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1556 Expect
(Tok_Right_Paren
, "`)`");
1558 if Token
= Tok_Right_Paren
then
1562 end Parse_String_Type_Declaration
;
1564 --------------------------------
1565 -- Parse_Variable_Declaration --
1566 --------------------------------
1568 procedure Parse_Variable_Declaration
1569 (In_Tree
: Project_Node_Tree_Ref
;
1570 Variable
: out Project_Node_Id
;
1571 Current_Project
: Project_Node_Id
;
1572 Current_Package
: Project_Node_Id
;
1573 Flags
: Processing_Flags
)
1575 Expression_Location
: Source_Ptr
;
1576 String_Type_Name
: Name_Id
:= No_Name
;
1577 Project_String_Type_Name
: Name_Id
:= No_Name
;
1578 Type_Location
: Source_Ptr
:= No_Location
;
1579 Project_Location
: Source_Ptr
:= No_Location
;
1580 Expression
: Project_Node_Id
:= Empty_Node
;
1581 Variable_Name
: constant Name_Id
:= Token_Name
;
1582 OK
: Boolean := True;
1586 Default_Project_Node
1587 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1588 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1589 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1591 -- Scan past the variable name
1595 if Token
= Tok_Colon
then
1597 -- Typed string variable declaration
1600 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1601 Expect
(Tok_Identifier
, "identifier");
1603 OK
:= Token
= Tok_Identifier
;
1606 String_Type_Name
:= Token_Name
;
1607 Type_Location
:= Token_Ptr
;
1610 if Token
= Tok_Dot
then
1611 Project_String_Type_Name
:= String_Type_Name
;
1612 Project_Location
:= Type_Location
;
1614 -- Scan past the dot
1617 Expect
(Tok_Identifier
, "identifier");
1619 if Token
= Tok_Identifier
then
1620 String_Type_Name
:= Token_Name
;
1621 Type_Location
:= Token_Ptr
;
1630 Proj
: Project_Node_Id
:= Current_Project
;
1631 Current
: Project_Node_Id
:= Empty_Node
;
1634 if Project_String_Type_Name
/= No_Name
then
1636 The_Project_Name_And_Node
: constant
1637 Tree_Private_Part
.Project_Name_And_Node
:=
1638 Tree_Private_Part
.Projects_Htable
.Get
1639 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1641 use Tree_Private_Part
;
1644 if The_Project_Name_And_Node
=
1645 Tree_Private_Part
.No_Project_Name_And_Node
1648 "unknown project """ &
1650 (Project_String_Type_Name
) &
1653 Current
:= Empty_Node
;
1656 First_String_Type_Of
1657 (The_Project_Name_And_Node
.Node
, In_Tree
);
1661 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1663 Current
:= Next_String_Type
(Current
, In_Tree
);
1669 -- Look for a string type with the correct name in this
1670 -- project or in any of its ancestors.
1674 First_String_Type_Of
(Proj
, In_Tree
);
1678 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1680 Current
:= Next_String_Type
(Current
, In_Tree
);
1683 exit when Present
(Current
);
1685 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1686 exit when No
(Proj
);
1690 if No
(Current
) then
1692 "unknown string type """ &
1693 Get_Name_String
(String_Type_Name
) &
1700 (Variable
, In_Tree
, To
=> Current
);
1707 Expect
(Tok_Colon_Equal
, "`:=`");
1709 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1711 if Token
= Tok_Colon_Equal
then
1715 -- Get the single string or string list value
1717 Expression_Location
:= Token_Ptr
;
1720 (In_Tree
=> In_Tree
,
1721 Expression
=> Expression
,
1723 Current_Project
=> Current_Project
,
1724 Current_Package
=> Current_Package
,
1725 Optional_Index
=> False);
1726 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1728 if Present
(Expression
) then
1729 -- A typed string must have a single string value, not a list
1731 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1732 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1736 "expression must be a single string", Expression_Location
);
1739 Set_Expression_Kind_Of
1741 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1746 The_Variable
: Project_Node_Id
:= Empty_Node
;
1749 if Present
(Current_Package
) then
1750 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1751 elsif Present
(Current_Project
) then
1752 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1755 while Present
(The_Variable
)
1756 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1758 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1761 if No
(The_Variable
) then
1762 if Present
(Current_Package
) then
1765 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1766 Set_First_Variable_Of
1767 (Current_Package
, In_Tree
, To
=> Variable
);
1769 elsif Present
(Current_Project
) then
1772 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1773 Set_First_Variable_Of
1774 (Current_Project
, In_Tree
, To
=> Variable
);
1778 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1779 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1782 Set_Expression_Kind_Of
1783 (The_Variable
, In_Tree
,
1784 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1787 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1788 Expression_Kind_Of
(Variable
, In_Tree
)
1791 "wrong expression kind for variable """ &
1793 (Name_Of
(The_Variable
, In_Tree
)) &
1795 Expression_Location
);
1802 end Parse_Variable_Declaration
;