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 Name
/= Snames
.Name_Ide
219 ((Qualif
= Aggregate
and then Name
/= Snames
.Name_Builder
)
221 (Qualif
= Aggregate_Library
and then Name
/= Snames
.Name_Builder
222 and then Name
/= Snames
.Name_Install
))
224 Error_Msg_Name_1
:= Name
;
227 "package %% is forbidden in aggregate projects",
228 Location_Of
(Current_Package
, In_Tree
));
230 end Check_Package_Allowed
;
232 -----------------------------
233 -- Check_Attribute_Allowed --
234 -----------------------------
236 procedure Check_Attribute_Allowed
237 (In_Tree
: Project_Node_Tree_Ref
;
238 Project
: Project_Node_Id
;
239 Attribute
: Project_Node_Id
;
240 Flags
: Processing_Flags
)
242 Qualif
: constant Project_Qualifier
:=
243 Project_Qualifier_Of
(Project
, In_Tree
);
244 Name
: constant Name_Id
:= Name_Of
(Attribute
, In_Tree
);
248 when Aggregate | Aggregate_Library
=>
249 if Name
= Snames
.Name_Languages
250 or else Name
= Snames
.Name_Source_Files
251 or else Name
= Snames
.Name_Source_List_File
252 or else Name
= Snames
.Name_Locally_Removed_Files
253 or else Name
= Snames
.Name_Excluded_Source_Files
254 or else Name
= Snames
.Name_Excluded_Source_List_File
255 or else Name
= Snames
.Name_Interfaces
256 or else Name
= Snames
.Name_Object_Dir
257 or else Name
= Snames
.Name_Exec_Dir
258 or else Name
= Snames
.Name_Source_Dirs
259 or else Name
= Snames
.Name_Inherit_Source_Path
261 (Qualif
= Aggregate
and then Name
= Snames
.Name_Library_Dir
)
263 (Qualif
= Aggregate
and then Name
= Snames
.Name_Library_Name
)
264 or else Name
= Snames
.Name_Main
265 or else Name
= Snames
.Name_Roots
266 or else Name
= Snames
.Name_Externally_Built
267 or else Name
= Snames
.Name_Executable
268 or else Name
= Snames
.Name_Executable_Suffix
269 or else Name
= Snames
.Name_Default_Switches
271 Error_Msg_Name_1
:= Name
;
274 "%% is not valid in aggregate projects",
275 Location_Of
(Attribute
, In_Tree
));
279 if Name
= Snames
.Name_Project_Files
280 or else Name
= Snames
.Name_Project_Path
281 or else Name
= Snames
.Name_External
283 Error_Msg_Name_1
:= Name
;
286 "%% is only valid in aggregate projects",
287 Location_Of
(Attribute
, In_Tree
));
290 end Check_Attribute_Allowed
;
292 ---------------------------------
293 -- Parse_Attribute_Declaration --
294 ---------------------------------
296 procedure Parse_Attribute_Declaration
297 (In_Tree
: Project_Node_Tree_Ref
;
298 Attribute
: out Project_Node_Id
;
299 First_Attribute
: Attribute_Node_Id
;
300 Current_Project
: Project_Node_Id
;
301 Current_Package
: Project_Node_Id
;
302 Packages_To_Check
: String_List_Access
;
303 Flags
: Processing_Flags
)
305 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
306 Full_Associative_Array
: Boolean := False;
307 Attribute_Name
: Name_Id
:= No_Name
;
308 Optional_Index
: Boolean := False;
309 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
311 procedure Process_Attribute_Name
;
312 -- Read the name of the attribute, and check its type
314 procedure Process_Associative_Array_Index
;
315 -- Read the index of the associative array and check its validity
317 ----------------------------
318 -- Process_Attribute_Name --
319 ----------------------------
321 procedure Process_Attribute_Name
is
325 Attribute_Name
:= Token_Name
;
326 Set_Name_Of
(Attribute
, In_Tree
, To
=> Attribute_Name
);
327 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
329 -- Find the attribute
332 Attribute_Node_Id_Of
(Attribute_Name
, First_Attribute
);
334 -- If the attribute cannot be found, create the attribute if inside
335 -- an unknown package.
337 if Current_Attribute
= Empty_Attribute
then
338 if Present
(Current_Package
)
339 and then Expression_Kind_Of
(Current_Package
, In_Tree
) = Ignored
341 Pkg_Id
:= Package_Id_Of
(Current_Package
, In_Tree
);
342 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
345 -- If not a valid attribute name, issue an error if inside
346 -- a package that need to be checked.
348 Ignore
:= Present
(Current_Package
) and then
349 Packages_To_Check
/= All_Packages
;
353 -- Check that we are not in a package to check
355 Get_Name_String
(Name_Of
(Current_Package
, In_Tree
));
357 for Index
in Packages_To_Check
'Range loop
358 if Name_Buffer
(1 .. Name_Len
) =
359 Packages_To_Check
(Index
).all
368 Error_Msg_Name_1
:= Token_Name
;
369 Error_Msg
(Flags
, "undefined attribute %%", Token_Ptr
);
373 -- Set, if appropriate the index case insensitivity flag
376 if Is_Read_Only
(Current_Attribute
) then
377 Error_Msg_Name_1
:= Token_Name
;
379 (Flags
, "read-only attribute %% cannot be given a value",
383 if Attribute_Kind_Of
(Current_Attribute
) in
384 All_Case_Insensitive_Associative_Array
386 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
390 Scan
(In_Tree
); -- past the attribute name
392 -- Set the expression kind of the attribute
394 if Current_Attribute
/= Empty_Attribute
then
395 Set_Expression_Kind_Of
396 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
397 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
399 end Process_Attribute_Name
;
401 -------------------------------------
402 -- Process_Associative_Array_Index --
403 -------------------------------------
405 procedure Process_Associative_Array_Index
is
407 -- If the attribute is not an associative array attribute, report
408 -- an error. If this information is still unknown, set the kind
409 -- to Associative_Array.
411 if Current_Attribute
/= Empty_Attribute
412 and then Attribute_Kind_Of
(Current_Attribute
) = Single
416 Get_Name_String
(Attribute_Name_Of
(Current_Attribute
))
417 & """ cannot be an associative array",
418 Location_Of
(Attribute
, In_Tree
));
420 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
421 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
424 Scan
(In_Tree
); -- past the left parenthesis
426 if Others_Allowed_For
(Current_Attribute
)
427 and then Token
= Tok_Others
429 Set_Associative_Array_Index_Of
430 (Attribute
, In_Tree
, All_Other_Names
);
431 Scan
(In_Tree
); -- past others
434 if Others_Allowed_For
(Current_Attribute
) then
435 Expect
(Tok_String_Literal
, "literal string or others");
437 Expect
(Tok_String_Literal
, "literal string");
440 if Token
= Tok_String_Literal
then
441 Get_Name_String
(Token_Name
);
443 if Case_Insensitive
(Attribute
, In_Tree
) then
444 To_Lower
(Name_Buffer
(1 .. Name_Len
));
447 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
448 Scan
(In_Tree
); -- past the literal string index
450 if Token
= Tok_At
then
451 case Attribute_Kind_Of
(Current_Attribute
) is
452 when Optional_Index_Associative_Array |
453 Optional_Index_Case_Insensitive_Associative_Array
=>
455 Expect
(Tok_Integer_Literal
, "integer literal");
457 if Token
= Tok_Integer_Literal
then
459 -- Set the source index value from given literal
462 Index
: constant Int
:=
463 UI_To_Int
(Int_Literal_Value
);
467 (Flags
, "index cannot be zero", Token_Ptr
);
470 (Attribute
, In_Tree
, To
=> Index
);
478 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
481 if Token
= Tok_Integer_Literal
then
489 Expect
(Tok_Right_Paren
, "`)`");
491 if Token
= Tok_Right_Paren
then
492 Scan
(In_Tree
); -- past the right parenthesis
494 end Process_Associative_Array_Index
;
499 (Of_Kind
=> N_Attribute_Declaration
, In_Tree
=> In_Tree
);
500 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
501 Set_Previous_Line_Node
(Attribute
);
507 -- Body or External may be an attribute name
509 if Token
= Tok_Body
then
510 Token
:= Tok_Identifier
;
511 Token_Name
:= Snames
.Name_Body
;
514 if Token
= Tok_External
then
515 Token
:= Tok_Identifier
;
516 Token_Name
:= Snames
.Name_External
;
519 Expect
(Tok_Identifier
, "identifier");
520 Process_Attribute_Name
;
521 Rename_Obsolescent_Attributes
(In_Tree
, Attribute
, Current_Package
);
522 Check_Attribute_Allowed
(In_Tree
, Current_Project
, Attribute
, Flags
);
524 -- Associative array attributes
526 if Token
= Tok_Left_Paren
then
527 Process_Associative_Array_Index
;
530 -- If it is an associative array attribute and there are no left
531 -- parenthesis, then this is a full associative array declaration.
532 -- Flag it as such for later processing of its value.
534 if Current_Attribute
/= Empty_Attribute
536 Attribute_Kind_Of
(Current_Attribute
) /= Single
538 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
539 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
542 Full_Associative_Array
:= True;
547 Expect
(Tok_Use
, "USE");
549 if Token
= Tok_Use
then
552 if Full_Associative_Array
then
554 -- Expect <project>'<same_attribute_name>, or
555 -- <project>.<same_package_name>'<same_attribute_name>
558 The_Project
: Project_Node_Id
:= Empty_Node
;
559 -- The node of the project where the associative array is
562 The_Package
: Project_Node_Id
:= Empty_Node
;
563 -- The node of the package where the associative array is
566 Project_Name
: Name_Id
:= No_Name
;
567 -- The name of the project where the associative array is
570 Location
: Source_Ptr
:= No_Location
;
571 -- The location of the project name
574 Expect
(Tok_Identifier
, "identifier");
576 if Token
= Tok_Identifier
then
577 Location
:= Token_Ptr
;
579 -- Find the project node in the imported project or
580 -- in the project being extended.
582 The_Project
:= Imported_Or_Extended_Project_Of
583 (Current_Project
, In_Tree
, Token_Name
);
585 if No
(The_Project
) then
586 Error_Msg
(Flags
, "unknown project", Location
);
587 Scan
(In_Tree
); -- past the project name
590 Project_Name
:= Token_Name
;
591 Scan
(In_Tree
); -- past the project name
593 -- If this is inside a package, a dot followed by the
594 -- name of the package must followed the project name.
596 if Present
(Current_Package
) then
597 Expect
(Tok_Dot
, "`.`");
599 if Token
/= Tok_Dot
then
600 The_Project
:= Empty_Node
;
603 Scan
(In_Tree
); -- past the dot
604 Expect
(Tok_Identifier
, "identifier");
606 if Token
/= Tok_Identifier
then
607 The_Project
:= Empty_Node
;
609 -- If it is not the same package name, issue error
612 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
614 The_Project
:= Empty_Node
;
616 (Flags
, "not the same package as " &
618 (Name_Of
(Current_Package
, In_Tree
)),
623 First_Package_Of
(The_Project
, In_Tree
);
625 -- Look for the package node
627 while Present
(The_Package
)
629 Name_Of
(The_Package
, In_Tree
) /= Token_Name
632 Next_Package_In_Project
633 (The_Package
, In_Tree
);
636 -- If the package cannot be found in the
637 -- project, issue an error.
639 if No
(The_Package
) then
640 The_Project
:= Empty_Node
;
641 Error_Msg_Name_2
:= Project_Name
;
642 Error_Msg_Name_1
:= Token_Name
;
645 "package % not declared in project %",
649 Scan
(In_Tree
); -- past the package name
656 if Present
(The_Project
) then
658 -- Looking for '<same attribute name>
660 Expect
(Tok_Apostrophe
, "`''`");
662 if Token
/= Tok_Apostrophe
then
663 The_Project
:= Empty_Node
;
666 Scan
(In_Tree
); -- past the apostrophe
667 Expect
(Tok_Identifier
, "identifier");
669 if Token
/= Tok_Identifier
then
670 The_Project
:= Empty_Node
;
673 -- If it is not the same attribute name, issue error
675 if Token_Name
/= Attribute_Name
then
676 The_Project
:= Empty_Node
;
677 Error_Msg_Name_1
:= Attribute_Name
;
679 (Flags
, "invalid name, should be %", Token_Ptr
);
682 Scan
(In_Tree
); -- past the attribute name
687 if No
(The_Project
) then
689 -- If there were any problem, set the attribute id to null,
690 -- so that the node will not be recorded.
692 Current_Attribute
:= Empty_Attribute
;
695 -- Set the appropriate field in the node.
696 -- Note that the index and the expression are nil. This
697 -- characterizes full associative array attribute
700 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
701 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
705 -- Other attribute declarations (not full associative array)
709 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
710 -- The location of the first token of the expression
712 Expression
: Project_Node_Id
:= Empty_Node
;
713 -- The expression, value for the attribute declaration
716 -- Get the expression value and set it in the attribute node
720 Expression
=> Expression
,
722 Current_Project
=> Current_Project
,
723 Current_Package
=> Current_Package
,
724 Optional_Index
=> Optional_Index
);
725 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
727 -- If the expression is legal, but not of the right kind
728 -- for the attribute, issue an error.
730 if Current_Attribute
/= Empty_Attribute
731 and then Present
(Expression
)
732 and then Variable_Kind_Of
(Current_Attribute
) /=
733 Expression_Kind_Of
(Expression
, In_Tree
)
735 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
738 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
742 (Flags
, "wrong expression kind for attribute """ &
744 (Attribute_Name_Of
(Current_Attribute
)) &
746 Expression_Location
);
753 -- If the attribute was not recognized, return an empty node.
754 -- It may be that it is not in a package to check, and the node will
755 -- not be added to the tree.
757 if Current_Attribute
= Empty_Attribute
then
758 Attribute
:= Empty_Node
;
761 Set_End_Of_Line
(Attribute
);
762 Set_Previous_Line_Node
(Attribute
);
763 end Parse_Attribute_Declaration
;
765 -----------------------------
766 -- Parse_Case_Construction --
767 -----------------------------
769 procedure Parse_Case_Construction
770 (In_Tree
: Project_Node_Tree_Ref
;
771 Case_Construction
: out Project_Node_Id
;
772 First_Attribute
: Attribute_Node_Id
;
773 Current_Project
: Project_Node_Id
;
774 Current_Package
: Project_Node_Id
;
775 Packages_To_Check
: String_List_Access
;
776 Is_Config_File
: Boolean;
777 Flags
: Processing_Flags
)
779 Current_Item
: Project_Node_Id
:= Empty_Node
;
780 Next_Item
: Project_Node_Id
:= Empty_Node
;
781 First_Case_Item
: Boolean := True;
783 Variable_Location
: Source_Ptr
:= No_Location
;
785 String_Type
: Project_Node_Id
:= Empty_Node
;
787 Case_Variable
: Project_Node_Id
:= Empty_Node
;
789 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
791 First_Choice
: Project_Node_Id
:= Empty_Node
;
793 When_Others
: Boolean := False;
794 -- Set to True when there is a "when others =>" clause
799 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
800 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
806 -- Get the switch variable
808 Expect
(Tok_Identifier
, "identifier");
810 if Token
= Tok_Identifier
then
811 Variable_Location
:= Token_Ptr
;
812 Parse_Variable_Reference
814 Variable
=> Case_Variable
,
816 Current_Project
=> Current_Project
,
817 Current_Package
=> Current_Package
);
818 Set_Case_Variable_Reference_Of
819 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
822 if Token
/= Tok_Is
then
827 if Present
(Case_Variable
) then
828 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
830 if Expression_Kind_Of
(Case_Variable
, In_Tree
) /= Single
then
833 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
834 """ is not a single string",
839 Expect
(Tok_Is
, "IS");
841 if Token
= Tok_Is
then
842 Set_End_Of_Line
(Case_Construction
);
843 Set_Previous_Line_Node
(Case_Construction
);
844 Set_Next_End_Node
(Case_Construction
);
851 Start_New_Case_Construction
(In_Tree
, String_Type
);
855 while Token
= Tok_When
loop
857 if First_Case_Item
then
860 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
861 Set_First_Case_Item_Of
862 (Case_Construction
, In_Tree
, To
=> Current_Item
);
863 First_Case_Item
:= False;
868 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
869 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
870 Current_Item
:= Next_Item
;
873 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
879 if Token
= Tok_Others
then
882 -- Scan past "others"
886 Expect
(Tok_Arrow
, "`=>`");
887 Set_End_Of_Line
(Current_Item
);
888 Set_Previous_Line_Node
(Current_Item
);
890 -- Empty_Node in Field1 of a Case_Item indicates
891 -- the "when others =>" branch.
893 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
895 Parse_Declarative_Items
897 Declarations
=> First_Declarative_Item
,
898 In_Zone
=> In_Case_Construction
,
899 First_Attribute
=> First_Attribute
,
900 Current_Project
=> Current_Project
,
901 Current_Package
=> Current_Package
,
902 Packages_To_Check
=> Packages_To_Check
,
903 Is_Config_File
=> Is_Config_File
,
906 -- "when others =>" must be the last branch, so save the
907 -- Case_Item and exit
909 Set_First_Declarative_Item_Of
910 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
916 First_Choice
=> First_Choice
,
918 String_Type
=> Present
(String_Type
));
919 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
921 Expect
(Tok_Arrow
, "`=>`");
922 Set_End_Of_Line
(Current_Item
);
923 Set_Previous_Line_Node
(Current_Item
);
925 Parse_Declarative_Items
927 Declarations
=> First_Declarative_Item
,
928 In_Zone
=> In_Case_Construction
,
929 First_Attribute
=> First_Attribute
,
930 Current_Project
=> Current_Project
,
931 Current_Package
=> Current_Package
,
932 Packages_To_Check
=> Packages_To_Check
,
933 Is_Config_File
=> Is_Config_File
,
936 Set_First_Declarative_Item_Of
937 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
942 End_Case_Construction
943 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
944 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
946 String_Type
=> Present
(String_Type
));
948 Expect
(Tok_End
, "`END CASE`");
949 Remove_Next_End_Node
;
951 if Token
= Tok_End
then
957 Expect
(Tok_Case
, "CASE");
965 Expect
(Tok_Semicolon
, "`;`");
966 Set_Previous_End_Node
(Case_Construction
);
968 end Parse_Case_Construction
;
970 -----------------------------
971 -- Parse_Declarative_Items --
972 -----------------------------
974 procedure Parse_Declarative_Items
975 (In_Tree
: Project_Node_Tree_Ref
;
976 Declarations
: out Project_Node_Id
;
978 First_Attribute
: Attribute_Node_Id
;
979 Current_Project
: Project_Node_Id
;
980 Current_Package
: Project_Node_Id
;
981 Packages_To_Check
: String_List_Access
;
982 Is_Config_File
: Boolean;
983 Flags
: Processing_Flags
)
985 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
986 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
987 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
988 Item_Location
: Source_Ptr
:= No_Location
;
991 Declarations
:= Empty_Node
;
994 -- We are always positioned at the token that precedes the first
995 -- token of the declarative element. Scan past it.
999 Item_Location
:= Token_Ptr
;
1002 when Tok_Identifier
=>
1004 if In_Zone
= In_Case_Construction
then
1006 -- Check if the variable has already been declared
1009 The_Variable
: Project_Node_Id
:= Empty_Node
;
1012 if Present
(Current_Package
) then
1014 First_Variable_Of
(Current_Package
, In_Tree
);
1015 elsif Present
(Current_Project
) then
1017 First_Variable_Of
(Current_Project
, In_Tree
);
1020 while Present
(The_Variable
)
1021 and then Name_Of
(The_Variable
, In_Tree
) /=
1024 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1027 -- It is an error to declare a variable in a case
1028 -- construction for the first time.
1030 if No
(The_Variable
) then
1033 "a variable cannot be declared " &
1034 "for the first time here",
1040 Parse_Variable_Declaration
1042 Current_Declaration
,
1043 Current_Project
=> Current_Project
,
1044 Current_Package
=> Current_Package
,
1047 Set_End_Of_Line
(Current_Declaration
);
1048 Set_Previous_Line_Node
(Current_Declaration
);
1052 Parse_Attribute_Declaration
1053 (In_Tree
=> In_Tree
,
1054 Attribute
=> Current_Declaration
,
1055 First_Attribute
=> First_Attribute
,
1056 Current_Project
=> Current_Project
,
1057 Current_Package
=> Current_Package
,
1058 Packages_To_Check
=> Packages_To_Check
,
1061 Set_End_Of_Line
(Current_Declaration
);
1062 Set_Previous_Line_Node
(Current_Declaration
);
1066 Scan
(In_Tree
); -- past "null"
1070 -- Package declaration
1072 if In_Zone
/= In_Project
then
1074 (Flags
, "a package cannot be declared here", Token_Ptr
);
1077 Parse_Package_Declaration
1078 (In_Tree
=> In_Tree
,
1079 Package_Declaration
=> Current_Declaration
,
1080 Current_Project
=> Current_Project
,
1081 Packages_To_Check
=> Packages_To_Check
,
1082 Is_Config_File
=> Is_Config_File
,
1085 Set_Previous_End_Node
(Current_Declaration
);
1089 -- Type String Declaration
1091 if In_Zone
/= In_Project
then
1093 "a string type cannot be declared here",
1097 Parse_String_Type_Declaration
1098 (In_Tree
=> In_Tree
,
1099 String_Type
=> Current_Declaration
,
1100 Current_Project
=> Current_Project
,
1103 Set_End_Of_Line
(Current_Declaration
);
1104 Set_Previous_Line_Node
(Current_Declaration
);
1108 -- Case construction
1110 Parse_Case_Construction
1111 (In_Tree
=> In_Tree
,
1112 Case_Construction
=> Current_Declaration
,
1113 First_Attribute
=> First_Attribute
,
1114 Current_Project
=> Current_Project
,
1115 Current_Package
=> Current_Package
,
1116 Packages_To_Check
=> Packages_To_Check
,
1117 Is_Config_File
=> Is_Config_File
,
1120 Set_Previous_End_Node
(Current_Declaration
);
1125 -- We are leaving Parse_Declarative_Items positioned
1126 -- at the first token after the list of declarative items.
1127 -- It could be "end" (for a project, a package declaration or
1128 -- a case construction) or "when" (for a case construction)
1132 Expect
(Tok_Semicolon
, "`;` after declarative items");
1134 -- Insert an N_Declarative_Item in the tree, but only if
1135 -- Current_Declaration is not an empty node.
1137 if Present
(Current_Declaration
) then
1138 if No
(Current_Declarative_Item
) then
1139 Current_Declarative_Item
:=
1140 Default_Project_Node
1141 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1142 Declarations
:= Current_Declarative_Item
;
1145 Next_Declarative_Item
:=
1146 Default_Project_Node
1147 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1148 Set_Next_Declarative_Item
1149 (Current_Declarative_Item
, In_Tree
,
1150 To
=> Next_Declarative_Item
);
1151 Current_Declarative_Item
:= Next_Declarative_Item
;
1154 Set_Current_Item_Node
1155 (Current_Declarative_Item
, In_Tree
,
1156 To
=> Current_Declaration
);
1158 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1161 end Parse_Declarative_Items
;
1163 -------------------------------
1164 -- Parse_Package_Declaration --
1165 -------------------------------
1167 procedure Parse_Package_Declaration
1168 (In_Tree
: Project_Node_Tree_Ref
;
1169 Package_Declaration
: out Project_Node_Id
;
1170 Current_Project
: Project_Node_Id
;
1171 Packages_To_Check
: String_List_Access
;
1172 Is_Config_File
: Boolean;
1173 Flags
: Processing_Flags
)
1175 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1176 Current_Package
: Package_Node_Id
:= Empty_Package
;
1177 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1178 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1179 Renaming
: Boolean := False;
1180 Extending
: Boolean := False;
1183 Package_Declaration
:=
1184 Default_Project_Node
1185 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1186 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1188 -- Scan past "package"
1191 Expect
(Tok_Identifier
, "identifier");
1193 if Token
= Tok_Identifier
then
1194 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1196 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1198 if Current_Package
= Empty_Package
then
1199 if not Quiet_Output
then
1201 List
: constant Strings
.String_List
:= Package_Name_List
;
1203 Name
: constant String := Get_Name_String
(Token_Name
);
1206 -- Check for possible misspelling of a known package name
1210 if Index
>= List
'Last then
1217 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1218 (Name
, List
(Index
).all);
1221 -- Issue warning(s) in verbose mode or when a possible
1222 -- misspelling has been found.
1224 if Verbose_Mode
or else Index
/= 0 then
1228 (Name_Of
(Package_Declaration
, In_Tree
)) &
1229 """ is not a known package name",
1234 Error_Msg
-- CODEFIX
1236 "\?possible misspelling of """ &
1237 List
(Index
).all & """", Token_Ptr
);
1242 -- Set the package declaration to "ignored" so that it is not
1243 -- processed by Prj.Proc.Process.
1245 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1247 -- Add the unknown package in the list of packages
1249 Add_Unknown_Package
(Token_Name
, Current_Package
);
1251 elsif Current_Package
= Unknown_Package
then
1253 -- Set the package declaration to "ignored" so that it is not
1254 -- processed by Prj.Proc.Process.
1256 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1259 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1263 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1266 Current
: Project_Node_Id
:=
1267 First_Package_Of
(Current_Project
, In_Tree
);
1270 while Present
(Current
)
1271 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1273 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1276 if Present
(Current
) then
1280 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1281 """ is declared twice in the same project",
1285 -- Add the package to the project list
1287 Set_Next_Package_In_Project
1288 (Package_Declaration
, In_Tree
,
1289 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1290 Set_First_Package_Of
1291 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1295 -- Scan past the package name
1300 Check_Package_Allowed
1301 (In_Tree
, Current_Project
, Package_Declaration
, Flags
);
1303 if Token
= Tok_Renames
then
1305 elsif Token
= Tok_Extends
then
1309 if Renaming
or else Extending
then
1310 if Is_Config_File
then
1313 "no package rename or extension in configuration projects",
1317 -- Scan past "renames" or "extends"
1321 Expect
(Tok_Identifier
, "identifier");
1323 if Token
= Tok_Identifier
then
1325 Project_Name
: constant Name_Id
:= Token_Name
;
1327 Clause
: Project_Node_Id
:=
1328 First_With_Clause_Of
(Current_Project
, In_Tree
);
1329 The_Project
: Project_Node_Id
:= Empty_Node
;
1330 Extended
: constant Project_Node_Id
:=
1332 (Project_Declaration_Of
1333 (Current_Project
, In_Tree
),
1336 while Present
(Clause
) loop
1337 -- Only non limited imported projects may be used in a
1338 -- renames declaration.
1341 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1342 exit when Present
(The_Project
)
1343 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1344 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1348 -- As we have not found the project in the imports, we check
1349 -- if it's the name of an eventual extended project.
1351 if Present
(Extended
)
1352 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1354 Set_Project_Of_Renamed_Package_Of
1355 (Package_Declaration
, In_Tree
, To
=> Extended
);
1357 Error_Msg_Name_1
:= Project_Name
;
1360 "% is not an imported or extended project", Token_Ptr
);
1363 Set_Project_Of_Renamed_Package_Of
1364 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1369 Expect
(Tok_Dot
, "`.`");
1371 if Token
= Tok_Dot
then
1373 Expect
(Tok_Identifier
, "identifier");
1375 if Token
= Tok_Identifier
then
1376 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1377 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1379 Present
(Project_Of_Renamed_Package_Of
1380 (Package_Declaration
, In_Tree
))
1383 Current
: Project_Node_Id
:=
1385 (Project_Of_Renamed_Package_Of
1386 (Package_Declaration
, In_Tree
),
1390 while Present
(Current
)
1391 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1394 Next_Package_In_Project
(Current
, In_Tree
);
1397 if No
(Current
) then
1400 Get_Name_String
(Token_Name
) &
1401 """ is not a package declared by the project",
1414 Expect
(Tok_Semicolon
, "`;`");
1415 Set_End_Of_Line
(Package_Declaration
);
1416 Set_Previous_Line_Node
(Package_Declaration
);
1418 elsif Token
= Tok_Is
then
1419 Set_End_Of_Line
(Package_Declaration
);
1420 Set_Previous_Line_Node
(Package_Declaration
);
1421 Set_Next_End_Node
(Package_Declaration
);
1423 Parse_Declarative_Items
1424 (In_Tree
=> In_Tree
,
1425 Declarations
=> First_Declarative_Item
,
1426 In_Zone
=> In_Package
,
1427 First_Attribute
=> First_Attribute
,
1428 Current_Project
=> Current_Project
,
1429 Current_Package
=> Package_Declaration
,
1430 Packages_To_Check
=> Packages_To_Check
,
1431 Is_Config_File
=> Is_Config_File
,
1434 Set_First_Declarative_Item_Of
1435 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1437 Expect
(Tok_End
, "END");
1439 if Token
= Tok_End
then
1446 -- We should have the name of the package after "end"
1448 Expect
(Tok_Identifier
, "identifier");
1450 if Token
= Tok_Identifier
1451 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1452 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1454 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1455 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1458 if Token
/= Tok_Semicolon
then
1460 -- Scan past the package name
1465 Expect
(Tok_Semicolon
, "`;`");
1466 Remove_Next_End_Node
;
1469 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1472 end Parse_Package_Declaration
;
1474 -----------------------------------
1475 -- Parse_String_Type_Declaration --
1476 -----------------------------------
1478 procedure Parse_String_Type_Declaration
1479 (In_Tree
: Project_Node_Tree_Ref
;
1480 String_Type
: out Project_Node_Id
;
1481 Current_Project
: Project_Node_Id
;
1482 Flags
: Processing_Flags
)
1484 Current
: Project_Node_Id
:= Empty_Node
;
1485 First_String
: Project_Node_Id
:= Empty_Node
;
1489 Default_Project_Node
1490 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1492 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1498 Expect
(Tok_Identifier
, "identifier");
1500 if Token
= Tok_Identifier
then
1501 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1503 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1504 while Present
(Current
)
1506 Name_Of
(Current
, In_Tree
) /= Token_Name
1508 Current
:= Next_String_Type
(Current
, In_Tree
);
1511 if Present
(Current
) then
1513 "duplicate string type name """ &
1514 Get_Name_String
(Token_Name
) &
1518 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1519 while Present
(Current
)
1520 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1522 Current
:= Next_Variable
(Current
, In_Tree
);
1525 if Present
(Current
) then
1528 Get_Name_String
(Token_Name
) &
1529 """ is already a variable name", Token_Ptr
);
1531 Set_Next_String_Type
1532 (String_Type
, In_Tree
,
1533 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1534 Set_First_String_Type_Of
1535 (Current_Project
, In_Tree
, To
=> String_Type
);
1539 -- Scan past the name
1544 Expect
(Tok_Is
, "IS");
1546 if Token
= Tok_Is
then
1550 Expect
(Tok_Left_Paren
, "`(`");
1552 if Token
= Tok_Left_Paren
then
1556 Parse_String_Type_List
1557 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1558 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1560 Expect
(Tok_Right_Paren
, "`)`");
1562 if Token
= Tok_Right_Paren
then
1565 end Parse_String_Type_Declaration
;
1567 --------------------------------
1568 -- Parse_Variable_Declaration --
1569 --------------------------------
1571 procedure Parse_Variable_Declaration
1572 (In_Tree
: Project_Node_Tree_Ref
;
1573 Variable
: out Project_Node_Id
;
1574 Current_Project
: Project_Node_Id
;
1575 Current_Package
: Project_Node_Id
;
1576 Flags
: Processing_Flags
)
1578 Expression_Location
: Source_Ptr
;
1579 String_Type_Name
: Name_Id
:= No_Name
;
1580 Project_String_Type_Name
: Name_Id
:= No_Name
;
1581 Type_Location
: Source_Ptr
:= No_Location
;
1582 Project_Location
: Source_Ptr
:= No_Location
;
1583 Expression
: Project_Node_Id
:= Empty_Node
;
1584 Variable_Name
: constant Name_Id
:= Token_Name
;
1585 OK
: Boolean := True;
1589 Default_Project_Node
1590 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1591 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1592 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1594 -- Scan past the variable name
1598 if Token
= Tok_Colon
then
1600 -- Typed string variable declaration
1603 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1604 Expect
(Tok_Identifier
, "identifier");
1606 OK
:= Token
= Tok_Identifier
;
1609 String_Type_Name
:= Token_Name
;
1610 Type_Location
:= Token_Ptr
;
1613 if Token
= Tok_Dot
then
1614 Project_String_Type_Name
:= String_Type_Name
;
1615 Project_Location
:= Type_Location
;
1617 -- Scan past the dot
1620 Expect
(Tok_Identifier
, "identifier");
1622 if Token
= Tok_Identifier
then
1623 String_Type_Name
:= Token_Name
;
1624 Type_Location
:= Token_Ptr
;
1633 Proj
: Project_Node_Id
:= Current_Project
;
1634 Current
: Project_Node_Id
:= Empty_Node
;
1637 if Project_String_Type_Name
/= No_Name
then
1639 The_Project_Name_And_Node
: constant
1640 Tree_Private_Part
.Project_Name_And_Node
:=
1641 Tree_Private_Part
.Projects_Htable
.Get
1642 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1644 use Tree_Private_Part
;
1647 if The_Project_Name_And_Node
=
1648 Tree_Private_Part
.No_Project_Name_And_Node
1651 "unknown project """ &
1653 (Project_String_Type_Name
) &
1656 Current
:= Empty_Node
;
1659 First_String_Type_Of
1660 (The_Project_Name_And_Node
.Node
, In_Tree
);
1664 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1666 Current
:= Next_String_Type
(Current
, In_Tree
);
1672 -- Look for a string type with the correct name in this
1673 -- project or in any of its ancestors.
1677 First_String_Type_Of
(Proj
, In_Tree
);
1681 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1683 Current
:= Next_String_Type
(Current
, In_Tree
);
1686 exit when Present
(Current
);
1688 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1689 exit when No
(Proj
);
1693 if No
(Current
) then
1695 "unknown string type """ &
1696 Get_Name_String
(String_Type_Name
) &
1703 (Variable
, In_Tree
, To
=> Current
);
1710 Expect
(Tok_Colon_Equal
, "`:=`");
1712 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1714 if Token
= Tok_Colon_Equal
then
1718 -- Get the single string or string list value
1720 Expression_Location
:= Token_Ptr
;
1723 (In_Tree
=> In_Tree
,
1724 Expression
=> Expression
,
1726 Current_Project
=> Current_Project
,
1727 Current_Package
=> Current_Package
,
1728 Optional_Index
=> False);
1729 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1731 if Present
(Expression
) then
1732 -- A typed string must have a single string value, not a list
1734 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1735 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1739 "expression must be a single string", Expression_Location
);
1742 Set_Expression_Kind_Of
1744 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1749 The_Variable
: Project_Node_Id
:= Empty_Node
;
1752 if Present
(Current_Package
) then
1753 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1754 elsif Present
(Current_Project
) then
1755 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1758 while Present
(The_Variable
)
1759 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1761 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1764 if No
(The_Variable
) then
1765 if Present
(Current_Package
) then
1768 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1769 Set_First_Variable_Of
1770 (Current_Package
, In_Tree
, To
=> Variable
);
1772 elsif Present
(Current_Project
) then
1775 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1776 Set_First_Variable_Of
1777 (Current_Project
, In_Tree
, To
=> Variable
);
1781 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1782 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1785 Set_Expression_Kind_Of
1786 (The_Variable
, In_Tree
,
1787 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1790 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1791 Expression_Kind_Of
(Variable
, In_Tree
)
1794 "wrong expression kind for variable """ &
1796 (Name_Of
(The_Variable
, In_Tree
)) &
1798 Expression_Location
);
1805 end Parse_Variable_Declaration
;