1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2015, 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
) and then not In_Tree
.Incomplete_With
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
)),
620 Scan
(In_Tree
); -- past the package name
623 if Present
(The_Project
) then
625 First_Package_Of
(The_Project
, In_Tree
);
627 -- Look for the package node
629 while Present
(The_Package
)
630 and then Name_Of
(The_Package
, In_Tree
) /=
634 Next_Package_In_Project
635 (The_Package
, In_Tree
);
638 -- If the package cannot be found in the
639 -- project, issue an error.
641 if No
(The_Package
) then
642 The_Project
:= Empty_Node
;
643 Error_Msg_Name_2
:= Project_Name
;
644 Error_Msg_Name_1
:= Token_Name
;
647 "package % not declared in project %",
652 Scan
(In_Tree
); -- past the package name
659 if Present
(The_Project
) or else In_Tree
.Incomplete_With
then
661 -- Looking for '<same attribute name>
663 Expect
(Tok_Apostrophe
, "`''`");
665 if Token
/= Tok_Apostrophe
then
666 The_Project
:= Empty_Node
;
669 Scan
(In_Tree
); -- past the apostrophe
670 Expect
(Tok_Identifier
, "identifier");
672 if Token
/= Tok_Identifier
then
673 The_Project
:= Empty_Node
;
676 -- If it is not the same attribute name, issue error
678 if Token_Name
/= Attribute_Name
then
679 The_Project
:= Empty_Node
;
680 Error_Msg_Name_1
:= Attribute_Name
;
682 (Flags
, "invalid name, should be %", Token_Ptr
);
685 Scan
(In_Tree
); -- past the attribute name
690 if No
(The_Project
) then
692 -- If there were any problem, set the attribute id to null,
693 -- so that the node will not be recorded.
695 Current_Attribute
:= Empty_Attribute
;
698 -- Set the appropriate field in the node.
699 -- Note that the index and the expression are nil. This
700 -- characterizes full associative array attribute
703 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
704 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
708 -- Other attribute declarations (not full associative array)
712 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
713 -- The location of the first token of the expression
715 Expression
: Project_Node_Id
:= Empty_Node
;
716 -- The expression, value for the attribute declaration
719 -- Get the expression value and set it in the attribute node
723 Expression
=> Expression
,
725 Current_Project
=> Current_Project
,
726 Current_Package
=> Current_Package
,
727 Optional_Index
=> Optional_Index
);
728 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
730 -- If the expression is legal, but not of the right kind
731 -- for the attribute, issue an error.
733 if Current_Attribute
/= Empty_Attribute
734 and then Present
(Expression
)
735 and then Variable_Kind_Of
(Current_Attribute
) /=
736 Expression_Kind_Of
(Expression
, In_Tree
)
738 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
741 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
745 (Flags
, "wrong expression kind for attribute """ &
747 (Attribute_Name_Of
(Current_Attribute
)) &
749 Expression_Location
);
756 -- If the attribute was not recognized, return an empty node.
757 -- It may be that it is not in a package to check, and the node will
758 -- not be added to the tree.
760 if Current_Attribute
= Empty_Attribute
then
761 Attribute
:= Empty_Node
;
764 Set_End_Of_Line
(Attribute
);
765 Set_Previous_Line_Node
(Attribute
);
766 end Parse_Attribute_Declaration
;
768 -----------------------------
769 -- Parse_Case_Construction --
770 -----------------------------
772 procedure Parse_Case_Construction
773 (In_Tree
: Project_Node_Tree_Ref
;
774 Case_Construction
: out Project_Node_Id
;
775 First_Attribute
: Attribute_Node_Id
;
776 Current_Project
: Project_Node_Id
;
777 Current_Package
: Project_Node_Id
;
778 Packages_To_Check
: String_List_Access
;
779 Is_Config_File
: Boolean;
780 Flags
: Processing_Flags
)
782 Current_Item
: Project_Node_Id
:= Empty_Node
;
783 Next_Item
: Project_Node_Id
:= Empty_Node
;
784 First_Case_Item
: Boolean := True;
786 Variable_Location
: Source_Ptr
:= No_Location
;
788 String_Type
: Project_Node_Id
:= Empty_Node
;
790 Case_Variable
: Project_Node_Id
:= Empty_Node
;
792 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
794 First_Choice
: Project_Node_Id
:= Empty_Node
;
796 When_Others
: Boolean := False;
797 -- Set to True when there is a "when others =>" clause
802 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
803 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
809 -- Get the switch variable
811 Expect
(Tok_Identifier
, "identifier");
813 if Token
= Tok_Identifier
then
814 Variable_Location
:= Token_Ptr
;
815 Parse_Variable_Reference
817 Variable
=> Case_Variable
,
819 Current_Project
=> Current_Project
,
820 Current_Package
=> Current_Package
);
821 Set_Case_Variable_Reference_Of
822 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
825 if Token
/= Tok_Is
then
830 if Present
(Case_Variable
) then
831 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
833 if Expression_Kind_Of
(Case_Variable
, In_Tree
) /= Single
then
836 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
837 """ is not a single string",
842 Expect
(Tok_Is
, "IS");
844 if Token
= Tok_Is
then
845 Set_End_Of_Line
(Case_Construction
);
846 Set_Previous_Line_Node
(Case_Construction
);
847 Set_Next_End_Node
(Case_Construction
);
854 Start_New_Case_Construction
(In_Tree
, String_Type
);
858 while Token
= Tok_When
loop
860 if First_Case_Item
then
863 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
864 Set_First_Case_Item_Of
865 (Case_Construction
, In_Tree
, To
=> Current_Item
);
866 First_Case_Item
:= False;
871 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
872 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
873 Current_Item
:= Next_Item
;
876 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
882 if Token
= Tok_Others
then
885 -- Scan past "others"
889 Expect
(Tok_Arrow
, "`=>`");
890 Set_End_Of_Line
(Current_Item
);
891 Set_Previous_Line_Node
(Current_Item
);
893 -- Empty_Node in Field1 of a Case_Item indicates
894 -- the "when others =>" branch.
896 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
898 Parse_Declarative_Items
900 Declarations
=> First_Declarative_Item
,
901 In_Zone
=> In_Case_Construction
,
902 First_Attribute
=> First_Attribute
,
903 Current_Project
=> Current_Project
,
904 Current_Package
=> Current_Package
,
905 Packages_To_Check
=> Packages_To_Check
,
906 Is_Config_File
=> Is_Config_File
,
909 -- "when others =>" must be the last branch, so save the
910 -- Case_Item and exit
912 Set_First_Declarative_Item_Of
913 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
919 First_Choice
=> First_Choice
,
921 String_Type
=> Present
(String_Type
));
922 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
924 Expect
(Tok_Arrow
, "`=>`");
925 Set_End_Of_Line
(Current_Item
);
926 Set_Previous_Line_Node
(Current_Item
);
928 Parse_Declarative_Items
930 Declarations
=> First_Declarative_Item
,
931 In_Zone
=> In_Case_Construction
,
932 First_Attribute
=> First_Attribute
,
933 Current_Project
=> Current_Project
,
934 Current_Package
=> Current_Package
,
935 Packages_To_Check
=> Packages_To_Check
,
936 Is_Config_File
=> Is_Config_File
,
939 Set_First_Declarative_Item_Of
940 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
945 End_Case_Construction
946 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
947 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
949 String_Type
=> Present
(String_Type
));
951 Expect
(Tok_End
, "`END CASE`");
952 Remove_Next_End_Node
;
954 if Token
= Tok_End
then
960 Expect
(Tok_Case
, "CASE");
968 Expect
(Tok_Semicolon
, "`;`");
969 Set_Previous_End_Node
(Case_Construction
);
971 end Parse_Case_Construction
;
973 -----------------------------
974 -- Parse_Declarative_Items --
975 -----------------------------
977 procedure Parse_Declarative_Items
978 (In_Tree
: Project_Node_Tree_Ref
;
979 Declarations
: out Project_Node_Id
;
981 First_Attribute
: Attribute_Node_Id
;
982 Current_Project
: Project_Node_Id
;
983 Current_Package
: Project_Node_Id
;
984 Packages_To_Check
: String_List_Access
;
985 Is_Config_File
: Boolean;
986 Flags
: Processing_Flags
)
988 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
989 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
990 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
991 Item_Location
: Source_Ptr
:= No_Location
;
994 Declarations
:= Empty_Node
;
997 -- We are always positioned at the token that precedes the first
998 -- token of the declarative element. Scan past it.
1002 Item_Location
:= Token_Ptr
;
1005 when Tok_Identifier
=>
1007 if In_Zone
= In_Case_Construction
then
1009 -- Check if the variable has already been declared
1012 The_Variable
: Project_Node_Id
:= Empty_Node
;
1015 if Present
(Current_Package
) then
1017 First_Variable_Of
(Current_Package
, In_Tree
);
1018 elsif Present
(Current_Project
) then
1020 First_Variable_Of
(Current_Project
, In_Tree
);
1023 while Present
(The_Variable
)
1024 and then Name_Of
(The_Variable
, In_Tree
) /=
1027 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1030 -- It is an error to declare a variable in a case
1031 -- construction for the first time.
1033 if No
(The_Variable
) then
1036 "a variable cannot be declared " &
1037 "for the first time here",
1043 Parse_Variable_Declaration
1045 Current_Declaration
,
1046 Current_Project
=> Current_Project
,
1047 Current_Package
=> Current_Package
,
1050 Set_End_Of_Line
(Current_Declaration
);
1051 Set_Previous_Line_Node
(Current_Declaration
);
1055 Parse_Attribute_Declaration
1056 (In_Tree
=> In_Tree
,
1057 Attribute
=> Current_Declaration
,
1058 First_Attribute
=> First_Attribute
,
1059 Current_Project
=> Current_Project
,
1060 Current_Package
=> Current_Package
,
1061 Packages_To_Check
=> Packages_To_Check
,
1064 Set_End_Of_Line
(Current_Declaration
);
1065 Set_Previous_Line_Node
(Current_Declaration
);
1069 Scan
(In_Tree
); -- past "null"
1073 -- Package declaration
1075 if In_Zone
/= In_Project
then
1077 (Flags
, "a package cannot be declared here", Token_Ptr
);
1080 Parse_Package_Declaration
1081 (In_Tree
=> In_Tree
,
1082 Package_Declaration
=> Current_Declaration
,
1083 Current_Project
=> Current_Project
,
1084 Packages_To_Check
=> Packages_To_Check
,
1085 Is_Config_File
=> Is_Config_File
,
1088 Set_Previous_End_Node
(Current_Declaration
);
1092 -- Type String Declaration
1094 if In_Zone
/= In_Project
then
1096 "a string type cannot be declared here",
1100 Parse_String_Type_Declaration
1101 (In_Tree
=> In_Tree
,
1102 String_Type
=> Current_Declaration
,
1103 Current_Project
=> Current_Project
,
1106 Set_End_Of_Line
(Current_Declaration
);
1107 Set_Previous_Line_Node
(Current_Declaration
);
1111 -- Case construction
1113 Parse_Case_Construction
1114 (In_Tree
=> In_Tree
,
1115 Case_Construction
=> Current_Declaration
,
1116 First_Attribute
=> First_Attribute
,
1117 Current_Project
=> Current_Project
,
1118 Current_Package
=> Current_Package
,
1119 Packages_To_Check
=> Packages_To_Check
,
1120 Is_Config_File
=> Is_Config_File
,
1123 Set_Previous_End_Node
(Current_Declaration
);
1128 -- We are leaving Parse_Declarative_Items positioned
1129 -- at the first token after the list of declarative items.
1130 -- It could be "end" (for a project, a package declaration or
1131 -- a case construction) or "when" (for a case construction)
1135 Expect
(Tok_Semicolon
, "`;` after declarative items");
1137 -- Insert an N_Declarative_Item in the tree, but only if
1138 -- Current_Declaration is not an empty node.
1140 if Present
(Current_Declaration
) then
1141 if No
(Current_Declarative_Item
) then
1142 Current_Declarative_Item
:=
1143 Default_Project_Node
1144 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1145 Declarations
:= Current_Declarative_Item
;
1148 Next_Declarative_Item
:=
1149 Default_Project_Node
1150 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1151 Set_Next_Declarative_Item
1152 (Current_Declarative_Item
, In_Tree
,
1153 To
=> Next_Declarative_Item
);
1154 Current_Declarative_Item
:= Next_Declarative_Item
;
1157 Set_Current_Item_Node
1158 (Current_Declarative_Item
, In_Tree
,
1159 To
=> Current_Declaration
);
1161 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1164 end Parse_Declarative_Items
;
1166 -------------------------------
1167 -- Parse_Package_Declaration --
1168 -------------------------------
1170 procedure Parse_Package_Declaration
1171 (In_Tree
: Project_Node_Tree_Ref
;
1172 Package_Declaration
: out Project_Node_Id
;
1173 Current_Project
: Project_Node_Id
;
1174 Packages_To_Check
: String_List_Access
;
1175 Is_Config_File
: Boolean;
1176 Flags
: Processing_Flags
)
1178 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1179 Current_Package
: Package_Node_Id
:= Empty_Package
;
1180 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1181 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1182 Renaming
: Boolean := False;
1183 Extending
: Boolean := False;
1186 Package_Declaration
:=
1187 Default_Project_Node
1188 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1189 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1191 -- Scan past "package"
1194 Expect
(Tok_Identifier
, "identifier");
1196 if Token
= Tok_Identifier
then
1197 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1199 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1201 if Current_Package
= Empty_Package
then
1202 if not Quiet_Output
then
1204 List
: constant Strings
.String_List
:= Package_Name_List
;
1206 Name
: constant String := Get_Name_String
(Token_Name
);
1209 -- Check for possible misspelling of a known package name
1213 if Index
>= List
'Last then
1220 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1221 (Name
, List
(Index
).all);
1224 -- Issue warning(s) in verbose mode or when a possible
1225 -- misspelling has been found.
1227 if Verbose_Mode
or else Index
/= 0 then
1231 (Name_Of
(Package_Declaration
, In_Tree
)) &
1232 """ is not a known package name",
1237 Error_Msg
-- CODEFIX
1239 "\?possible misspelling of """ &
1240 List
(Index
).all & """", Token_Ptr
);
1245 -- Set the package declaration to "ignored" so that it is not
1246 -- processed by Prj.Proc.Process.
1248 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1250 -- Add the unknown package in the list of packages
1252 Add_Unknown_Package
(Token_Name
, Current_Package
);
1254 elsif Current_Package
= Unknown_Package
then
1256 -- Set the package declaration to "ignored" so that it is not
1257 -- processed by Prj.Proc.Process.
1259 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1262 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1266 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1269 Current
: Project_Node_Id
:=
1270 First_Package_Of
(Current_Project
, In_Tree
);
1273 while Present
(Current
)
1274 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1276 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1279 if Present
(Current
) then
1283 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1284 """ is declared twice in the same project",
1288 -- Add the package to the project list
1290 Set_Next_Package_In_Project
1291 (Package_Declaration
, In_Tree
,
1292 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1293 Set_First_Package_Of
1294 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1298 -- Scan past the package name
1303 Check_Package_Allowed
1304 (In_Tree
, Current_Project
, Package_Declaration
, Flags
);
1306 if Token
= Tok_Renames
then
1308 elsif Token
= Tok_Extends
then
1312 if Renaming
or else Extending
then
1313 if Is_Config_File
then
1316 "no package rename or extension in configuration projects",
1320 -- Scan past "renames" or "extends"
1324 Expect
(Tok_Identifier
, "identifier");
1326 if Token
= Tok_Identifier
then
1328 Project_Name
: constant Name_Id
:= Token_Name
;
1330 Clause
: Project_Node_Id
:=
1331 First_With_Clause_Of
(Current_Project
, In_Tree
);
1332 The_Project
: Project_Node_Id
:= Empty_Node
;
1333 Extended
: constant Project_Node_Id
:=
1335 (Project_Declaration_Of
1336 (Current_Project
, In_Tree
),
1339 while Present
(Clause
) loop
1340 -- Only non limited imported projects may be used in a
1341 -- renames declaration.
1344 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1345 exit when Present
(The_Project
)
1346 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1347 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1351 -- As we have not found the project in the imports, we check
1352 -- if it's the name of an eventual extended project.
1354 if Present
(Extended
)
1355 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1357 Set_Project_Of_Renamed_Package_Of
1358 (Package_Declaration
, In_Tree
, To
=> Extended
);
1360 Error_Msg_Name_1
:= Project_Name
;
1363 "% is not an imported or extended project", Token_Ptr
);
1366 Set_Project_Of_Renamed_Package_Of
1367 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1372 Expect
(Tok_Dot
, "`.`");
1374 if Token
= Tok_Dot
then
1376 Expect
(Tok_Identifier
, "identifier");
1378 if Token
= Tok_Identifier
then
1379 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1380 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1382 Present
(Project_Of_Renamed_Package_Of
1383 (Package_Declaration
, In_Tree
))
1386 Current
: Project_Node_Id
:=
1388 (Project_Of_Renamed_Package_Of
1389 (Package_Declaration
, In_Tree
),
1393 while Present
(Current
)
1394 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1397 Next_Package_In_Project
(Current
, In_Tree
);
1400 if No
(Current
) then
1403 Get_Name_String
(Token_Name
) &
1404 """ is not a package declared by the project",
1417 Expect
(Tok_Semicolon
, "`;`");
1418 Set_End_Of_Line
(Package_Declaration
);
1419 Set_Previous_Line_Node
(Package_Declaration
);
1421 elsif Token
= Tok_Is
then
1422 Set_End_Of_Line
(Package_Declaration
);
1423 Set_Previous_Line_Node
(Package_Declaration
);
1424 Set_Next_End_Node
(Package_Declaration
);
1426 Parse_Declarative_Items
1427 (In_Tree
=> In_Tree
,
1428 Declarations
=> First_Declarative_Item
,
1429 In_Zone
=> In_Package
,
1430 First_Attribute
=> First_Attribute
,
1431 Current_Project
=> Current_Project
,
1432 Current_Package
=> Package_Declaration
,
1433 Packages_To_Check
=> Packages_To_Check
,
1434 Is_Config_File
=> Is_Config_File
,
1437 Set_First_Declarative_Item_Of
1438 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1440 Expect
(Tok_End
, "END");
1442 if Token
= Tok_End
then
1449 -- We should have the name of the package after "end"
1451 Expect
(Tok_Identifier
, "identifier");
1453 if Token
= Tok_Identifier
1454 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1455 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1457 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1458 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1461 if Token
/= Tok_Semicolon
then
1463 -- Scan past the package name
1468 Expect
(Tok_Semicolon
, "`;`");
1469 Remove_Next_End_Node
;
1472 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1475 end Parse_Package_Declaration
;
1477 -----------------------------------
1478 -- Parse_String_Type_Declaration --
1479 -----------------------------------
1481 procedure Parse_String_Type_Declaration
1482 (In_Tree
: Project_Node_Tree_Ref
;
1483 String_Type
: out Project_Node_Id
;
1484 Current_Project
: Project_Node_Id
;
1485 Flags
: Processing_Flags
)
1487 Current
: Project_Node_Id
:= Empty_Node
;
1488 First_String
: Project_Node_Id
:= Empty_Node
;
1492 Default_Project_Node
1493 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1495 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1501 Expect
(Tok_Identifier
, "identifier");
1503 if Token
= Tok_Identifier
then
1504 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1506 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1507 while Present
(Current
)
1509 Name_Of
(Current
, In_Tree
) /= Token_Name
1511 Current
:= Next_String_Type
(Current
, In_Tree
);
1514 if Present
(Current
) then
1516 "duplicate string type name """ &
1517 Get_Name_String
(Token_Name
) &
1521 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1522 while Present
(Current
)
1523 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1525 Current
:= Next_Variable
(Current
, In_Tree
);
1528 if Present
(Current
) then
1531 Get_Name_String
(Token_Name
) &
1532 """ is already a variable name", Token_Ptr
);
1534 Set_Next_String_Type
1535 (String_Type
, In_Tree
,
1536 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1537 Set_First_String_Type_Of
1538 (Current_Project
, In_Tree
, To
=> String_Type
);
1542 -- Scan past the name
1547 Expect
(Tok_Is
, "IS");
1549 if Token
= Tok_Is
then
1553 Expect
(Tok_Left_Paren
, "`(`");
1555 if Token
= Tok_Left_Paren
then
1559 Parse_String_Type_List
1560 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1561 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1563 Expect
(Tok_Right_Paren
, "`)`");
1565 if Token
= Tok_Right_Paren
then
1568 end Parse_String_Type_Declaration
;
1570 --------------------------------
1571 -- Parse_Variable_Declaration --
1572 --------------------------------
1574 procedure Parse_Variable_Declaration
1575 (In_Tree
: Project_Node_Tree_Ref
;
1576 Variable
: out Project_Node_Id
;
1577 Current_Project
: Project_Node_Id
;
1578 Current_Package
: Project_Node_Id
;
1579 Flags
: Processing_Flags
)
1581 Expression_Location
: Source_Ptr
;
1582 String_Type_Name
: Name_Id
:= No_Name
;
1583 Project_String_Type_Name
: Name_Id
:= No_Name
;
1584 Type_Location
: Source_Ptr
:= No_Location
;
1585 Project_Location
: Source_Ptr
:= No_Location
;
1586 Expression
: Project_Node_Id
:= Empty_Node
;
1587 Variable_Name
: constant Name_Id
:= Token_Name
;
1588 OK
: Boolean := True;
1592 Default_Project_Node
1593 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1594 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1595 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1597 -- Scan past the variable name
1601 if Token
= Tok_Colon
then
1603 -- Typed string variable declaration
1606 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1607 Expect
(Tok_Identifier
, "identifier");
1609 OK
:= Token
= Tok_Identifier
;
1612 String_Type_Name
:= Token_Name
;
1613 Type_Location
:= Token_Ptr
;
1616 if Token
= Tok_Dot
then
1617 Project_String_Type_Name
:= String_Type_Name
;
1618 Project_Location
:= Type_Location
;
1620 -- Scan past the dot
1623 Expect
(Tok_Identifier
, "identifier");
1625 if Token
= Tok_Identifier
then
1626 String_Type_Name
:= Token_Name
;
1627 Type_Location
:= Token_Ptr
;
1636 Proj
: Project_Node_Id
:= Current_Project
;
1637 Current
: Project_Node_Id
:= Empty_Node
;
1640 if Project_String_Type_Name
/= No_Name
then
1642 The_Project_Name_And_Node
: constant
1643 Tree_Private_Part
.Project_Name_And_Node
:=
1644 Tree_Private_Part
.Projects_Htable
.Get
1645 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1647 use Tree_Private_Part
;
1650 if The_Project_Name_And_Node
=
1651 Tree_Private_Part
.No_Project_Name_And_Node
1654 "unknown project """ &
1656 (Project_String_Type_Name
) &
1659 Current
:= Empty_Node
;
1662 First_String_Type_Of
1663 (The_Project_Name_And_Node
.Node
, In_Tree
);
1667 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1669 Current
:= Next_String_Type
(Current
, In_Tree
);
1675 -- Look for a string type with the correct name in this
1676 -- project or in any of its ancestors.
1680 First_String_Type_Of
(Proj
, In_Tree
);
1684 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1686 Current
:= Next_String_Type
(Current
, In_Tree
);
1689 exit when Present
(Current
);
1691 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1692 exit when No
(Proj
);
1696 if No
(Current
) then
1698 "unknown string type """ &
1699 Get_Name_String
(String_Type_Name
) &
1706 (Variable
, In_Tree
, To
=> Current
);
1713 Expect
(Tok_Colon_Equal
, "`:=`");
1715 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1717 if Token
= Tok_Colon_Equal
then
1721 -- Get the single string or string list value
1723 Expression_Location
:= Token_Ptr
;
1726 (In_Tree
=> In_Tree
,
1727 Expression
=> Expression
,
1729 Current_Project
=> Current_Project
,
1730 Current_Package
=> Current_Package
,
1731 Optional_Index
=> False);
1732 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1734 if Present
(Expression
) then
1735 -- A typed string must have a single string value, not a list
1737 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1738 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1742 "expression must be a single string", Expression_Location
);
1745 Set_Expression_Kind_Of
1747 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1752 The_Variable
: Project_Node_Id
:= Empty_Node
;
1755 if Present
(Current_Package
) then
1756 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1757 elsif Present
(Current_Project
) then
1758 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1761 while Present
(The_Variable
)
1762 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1764 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1767 if No
(The_Variable
) then
1768 if Present
(Current_Package
) then
1771 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1772 Set_First_Variable_Of
1773 (Current_Package
, In_Tree
, To
=> Variable
);
1775 elsif Present
(Current_Project
) then
1778 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1779 Set_First_Variable_Of
1780 (Current_Project
, In_Tree
, To
=> Variable
);
1784 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1785 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1788 Set_Expression_Kind_Of
1789 (The_Variable
, In_Tree
,
1790 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1793 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1794 Expression_Kind_Of
(Variable
, In_Tree
)
1797 "wrong expression kind for variable """ &
1799 (Name_Of
(The_Variable
, In_Tree
)) &
1801 Expression_Location
);
1808 end Parse_Variable_Declaration
;