1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2011, 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
in Aggregate_Project
218 and then Name
/= Snames
.Name_Builder
220 Error_Msg_Name_1
:= Name
;
223 "package %% is forbidden in aggregate projects",
224 Location_Of
(Current_Package
, In_Tree
));
226 end Check_Package_Allowed
;
228 -----------------------------
229 -- Check_Attribute_Allowed --
230 -----------------------------
232 procedure Check_Attribute_Allowed
233 (In_Tree
: Project_Node_Tree_Ref
;
234 Project
: Project_Node_Id
;
235 Attribute
: Project_Node_Id
;
236 Flags
: Processing_Flags
)
238 Qualif
: constant Project_Qualifier
:=
239 Project_Qualifier_Of
(Project
, In_Tree
);
240 Name
: constant Name_Id
:= Name_Of
(Attribute
, In_Tree
);
244 when Aggregate | Aggregate_Library
=>
245 if Name
= Snames
.Name_Languages
246 or else Name
= Snames
.Name_Source_Files
247 or else Name
= Snames
.Name_Source_List_File
248 or else Name
= Snames
.Name_Locally_Removed_Files
249 or else Name
= Snames
.Name_Excluded_Source_Files
250 or else Name
= Snames
.Name_Excluded_Source_List_File
251 or else Name
= Snames
.Name_Interfaces
252 or else Name
= Snames
.Name_Object_Dir
253 or else Name
= Snames
.Name_Exec_Dir
254 or else Name
= Snames
.Name_Source_Dirs
255 or else Name
= Snames
.Name_Inherit_Source_Path
257 Error_Msg_Name_1
:= Name
;
260 "%% is not valid in aggregate projects",
261 Location_Of
(Attribute
, In_Tree
));
265 if Name
= Snames
.Name_Project_Files
266 or else Name
= Snames
.Name_Project_Path
267 or else Name
= Snames
.Name_External
269 Error_Msg_Name_1
:= Name
;
272 "%% is only valid in aggregate projects",
273 Location_Of
(Attribute
, In_Tree
));
276 end Check_Attribute_Allowed
;
278 ---------------------------------
279 -- Parse_Attribute_Declaration --
280 ---------------------------------
282 procedure Parse_Attribute_Declaration
283 (In_Tree
: Project_Node_Tree_Ref
;
284 Attribute
: out Project_Node_Id
;
285 First_Attribute
: Attribute_Node_Id
;
286 Current_Project
: Project_Node_Id
;
287 Current_Package
: Project_Node_Id
;
288 Packages_To_Check
: String_List_Access
;
289 Flags
: Processing_Flags
)
291 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
292 Full_Associative_Array
: Boolean := False;
293 Attribute_Name
: Name_Id
:= No_Name
;
294 Optional_Index
: Boolean := False;
295 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
297 procedure Process_Attribute_Name
;
298 -- Read the name of the attribute, and check its type
300 procedure Process_Associative_Array_Index
;
301 -- Read the index of the associative array and check its validity
303 ----------------------------
304 -- Process_Attribute_Name --
305 ----------------------------
307 procedure Process_Attribute_Name
is
311 Attribute_Name
:= Token_Name
;
312 Set_Name_Of
(Attribute
, In_Tree
, To
=> Attribute_Name
);
313 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
315 -- Find the attribute
318 Attribute_Node_Id_Of
(Attribute_Name
, First_Attribute
);
320 -- If the attribute cannot be found, create the attribute if inside
321 -- an unknown package.
323 if Current_Attribute
= Empty_Attribute
then
324 if Present
(Current_Package
)
325 and then Expression_Kind_Of
(Current_Package
, In_Tree
) = Ignored
327 Pkg_Id
:= Package_Id_Of
(Current_Package
, In_Tree
);
328 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
331 -- If not a valid attribute name, issue an error if inside
332 -- a package that need to be checked.
334 Ignore
:= Present
(Current_Package
) and then
335 Packages_To_Check
/= All_Packages
;
339 -- Check that we are not in a package to check
341 Get_Name_String
(Name_Of
(Current_Package
, In_Tree
));
343 for Index
in Packages_To_Check
'Range loop
344 if Name_Buffer
(1 .. Name_Len
) =
345 Packages_To_Check
(Index
).all
354 Error_Msg_Name_1
:= Token_Name
;
355 Error_Msg
(Flags
, "undefined attribute %%", Token_Ptr
);
359 -- Set, if appropriate the index case insensitivity flag
362 if Is_Read_Only
(Current_Attribute
) then
363 Error_Msg_Name_1
:= Token_Name
;
365 (Flags
, "read-only attribute %% cannot be given a value",
369 if Attribute_Kind_Of
(Current_Attribute
) in
370 All_Case_Insensitive_Associative_Array
372 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
376 Scan
(In_Tree
); -- past the attribute name
378 -- Set the expression kind of the attribute
380 if Current_Attribute
/= Empty_Attribute
then
381 Set_Expression_Kind_Of
382 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
383 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
385 end Process_Attribute_Name
;
387 -------------------------------------
388 -- Process_Associative_Array_Index --
389 -------------------------------------
391 procedure Process_Associative_Array_Index
is
393 -- If the attribute is not an associative array attribute, report
394 -- an error. If this information is still unknown, set the kind
395 -- to Associative_Array.
397 if Current_Attribute
/= Empty_Attribute
398 and then Attribute_Kind_Of
(Current_Attribute
) = Single
402 Get_Name_String
(Attribute_Name_Of
(Current_Attribute
))
403 & """ cannot be an associative array",
404 Location_Of
(Attribute
, In_Tree
));
406 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
407 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
410 Scan
(In_Tree
); -- past the left parenthesis
412 if Others_Allowed_For
(Current_Attribute
)
413 and then Token
= Tok_Others
415 Set_Associative_Array_Index_Of
416 (Attribute
, In_Tree
, All_Other_Names
);
417 Scan
(In_Tree
); -- past others
420 if Others_Allowed_For
(Current_Attribute
) then
421 Expect
(Tok_String_Literal
, "literal string or others");
423 Expect
(Tok_String_Literal
, "literal string");
426 if Token
= Tok_String_Literal
then
427 Get_Name_String
(Token_Name
);
429 if Case_Insensitive
(Attribute
, In_Tree
) then
430 To_Lower
(Name_Buffer
(1 .. Name_Len
));
433 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
434 Scan
(In_Tree
); -- past the literal string index
436 if Token
= Tok_At
then
437 case Attribute_Kind_Of
(Current_Attribute
) is
438 when Optional_Index_Associative_Array |
439 Optional_Index_Case_Insensitive_Associative_Array
=>
441 Expect
(Tok_Integer_Literal
, "integer literal");
443 if Token
= Tok_Integer_Literal
then
445 -- Set the source index value from given literal
448 Index
: constant Int
:=
449 UI_To_Int
(Int_Literal_Value
);
453 (Flags
, "index cannot be zero", Token_Ptr
);
456 (Attribute
, In_Tree
, To
=> Index
);
464 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
467 if Token
= Tok_Integer_Literal
then
475 Expect
(Tok_Right_Paren
, "`)`");
477 if Token
= Tok_Right_Paren
then
478 Scan
(In_Tree
); -- past the right parenthesis
480 end Process_Associative_Array_Index
;
485 (Of_Kind
=> N_Attribute_Declaration
, In_Tree
=> In_Tree
);
486 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
487 Set_Previous_Line_Node
(Attribute
);
493 -- Body or External may be an attribute name
495 if Token
= Tok_Body
then
496 Token
:= Tok_Identifier
;
497 Token_Name
:= Snames
.Name_Body
;
500 if Token
= Tok_External
then
501 Token
:= Tok_Identifier
;
502 Token_Name
:= Snames
.Name_External
;
505 Expect
(Tok_Identifier
, "identifier");
506 Process_Attribute_Name
;
507 Rename_Obsolescent_Attributes
(In_Tree
, Attribute
, Current_Package
);
508 Check_Attribute_Allowed
(In_Tree
, Current_Project
, Attribute
, Flags
);
510 -- Associative array attributes
512 if Token
= Tok_Left_Paren
then
513 Process_Associative_Array_Index
;
516 -- If it is an associative array attribute and there are no left
517 -- parenthesis, then this is a full associative array declaration.
518 -- Flag it as such for later processing of its value.
520 if Current_Attribute
/= Empty_Attribute
522 Attribute_Kind_Of
(Current_Attribute
) /= Single
524 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
525 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
528 Full_Associative_Array
:= True;
533 Expect
(Tok_Use
, "USE");
535 if Token
= Tok_Use
then
538 if Full_Associative_Array
then
540 -- Expect <project>'<same_attribute_name>, or
541 -- <project>.<same_package_name>'<same_attribute_name>
544 The_Project
: Project_Node_Id
:= Empty_Node
;
545 -- The node of the project where the associative array is
548 The_Package
: Project_Node_Id
:= Empty_Node
;
549 -- The node of the package where the associative array is
552 Project_Name
: Name_Id
:= No_Name
;
553 -- The name of the project where the associative array is
556 Location
: Source_Ptr
:= No_Location
;
557 -- The location of the project name
560 Expect
(Tok_Identifier
, "identifier");
562 if Token
= Tok_Identifier
then
563 Location
:= Token_Ptr
;
565 -- Find the project node in the imported project or
566 -- in the project being extended.
568 The_Project
:= Imported_Or_Extended_Project_Of
569 (Current_Project
, In_Tree
, Token_Name
);
571 if No
(The_Project
) then
572 Error_Msg
(Flags
, "unknown project", Location
);
573 Scan
(In_Tree
); -- past the project name
576 Project_Name
:= Token_Name
;
577 Scan
(In_Tree
); -- past the project name
579 -- If this is inside a package, a dot followed by the
580 -- name of the package must followed the project name.
582 if Present
(Current_Package
) then
583 Expect
(Tok_Dot
, "`.`");
585 if Token
/= Tok_Dot
then
586 The_Project
:= Empty_Node
;
589 Scan
(In_Tree
); -- past the dot
590 Expect
(Tok_Identifier
, "identifier");
592 if Token
/= Tok_Identifier
then
593 The_Project
:= Empty_Node
;
595 -- If it is not the same package name, issue error
598 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
600 The_Project
:= Empty_Node
;
602 (Flags
, "not the same package as " &
604 (Name_Of
(Current_Package
, In_Tree
)),
609 First_Package_Of
(The_Project
, In_Tree
);
611 -- Look for the package node
613 while Present
(The_Package
)
615 Name_Of
(The_Package
, In_Tree
) /= Token_Name
618 Next_Package_In_Project
619 (The_Package
, In_Tree
);
622 -- If the package cannot be found in the
623 -- project, issue an error.
625 if No
(The_Package
) then
626 The_Project
:= Empty_Node
;
627 Error_Msg_Name_2
:= Project_Name
;
628 Error_Msg_Name_1
:= Token_Name
;
631 "package % not declared in project %",
635 Scan
(In_Tree
); -- past the package name
642 if Present
(The_Project
) then
644 -- Looking for '<same attribute name>
646 Expect
(Tok_Apostrophe
, "`''`");
648 if Token
/= Tok_Apostrophe
then
649 The_Project
:= Empty_Node
;
652 Scan
(In_Tree
); -- past the apostrophe
653 Expect
(Tok_Identifier
, "identifier");
655 if Token
/= Tok_Identifier
then
656 The_Project
:= Empty_Node
;
659 -- If it is not the same attribute name, issue error
661 if Token_Name
/= Attribute_Name
then
662 The_Project
:= Empty_Node
;
663 Error_Msg_Name_1
:= Attribute_Name
;
665 (Flags
, "invalid name, should be %", Token_Ptr
);
668 Scan
(In_Tree
); -- past the attribute name
673 if No
(The_Project
) then
675 -- If there were any problem, set the attribute id to null,
676 -- so that the node will not be recorded.
678 Current_Attribute
:= Empty_Attribute
;
681 -- Set the appropriate field in the node.
682 -- Note that the index and the expression are nil. This
683 -- characterizes full associative array attribute
686 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
687 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
691 -- Other attribute declarations (not full associative array)
695 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
696 -- The location of the first token of the expression
698 Expression
: Project_Node_Id
:= Empty_Node
;
699 -- The expression, value for the attribute declaration
702 -- Get the expression value and set it in the attribute node
706 Expression
=> Expression
,
708 Current_Project
=> Current_Project
,
709 Current_Package
=> Current_Package
,
710 Optional_Index
=> Optional_Index
);
711 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
713 -- If the expression is legal, but not of the right kind
714 -- for the attribute, issue an error.
716 if Current_Attribute
/= Empty_Attribute
717 and then Present
(Expression
)
718 and then Variable_Kind_Of
(Current_Attribute
) /=
719 Expression_Kind_Of
(Expression
, In_Tree
)
721 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
724 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
728 (Flags
, "wrong expression kind for attribute """ &
730 (Attribute_Name_Of
(Current_Attribute
)) &
732 Expression_Location
);
739 -- If the attribute was not recognized, return an empty node.
740 -- It may be that it is not in a package to check, and the node will
741 -- not be added to the tree.
743 if Current_Attribute
= Empty_Attribute
then
744 Attribute
:= Empty_Node
;
747 Set_End_Of_Line
(Attribute
);
748 Set_Previous_Line_Node
(Attribute
);
749 end Parse_Attribute_Declaration
;
751 -----------------------------
752 -- Parse_Case_Construction --
753 -----------------------------
755 procedure Parse_Case_Construction
756 (In_Tree
: Project_Node_Tree_Ref
;
757 Case_Construction
: out Project_Node_Id
;
758 First_Attribute
: Attribute_Node_Id
;
759 Current_Project
: Project_Node_Id
;
760 Current_Package
: Project_Node_Id
;
761 Packages_To_Check
: String_List_Access
;
762 Is_Config_File
: Boolean;
763 Flags
: Processing_Flags
)
765 Current_Item
: Project_Node_Id
:= Empty_Node
;
766 Next_Item
: Project_Node_Id
:= Empty_Node
;
767 First_Case_Item
: Boolean := True;
769 Variable_Location
: Source_Ptr
:= No_Location
;
771 String_Type
: Project_Node_Id
:= Empty_Node
;
773 Case_Variable
: Project_Node_Id
:= Empty_Node
;
775 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
777 First_Choice
: Project_Node_Id
:= Empty_Node
;
779 When_Others
: Boolean := False;
780 -- Set to True when there is a "when others =>" clause
785 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
786 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
792 -- Get the switch variable
794 Expect
(Tok_Identifier
, "identifier");
796 if Token
= Tok_Identifier
then
797 Variable_Location
:= Token_Ptr
;
798 Parse_Variable_Reference
800 Variable
=> Case_Variable
,
802 Current_Project
=> Current_Project
,
803 Current_Package
=> Current_Package
);
804 Set_Case_Variable_Reference_Of
805 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
808 if Token
/= Tok_Is
then
813 if Present
(Case_Variable
) then
814 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
816 if No
(String_Type
) then
819 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
825 Expect
(Tok_Is
, "IS");
827 if Token
= Tok_Is
then
828 Set_End_Of_Line
(Case_Construction
);
829 Set_Previous_Line_Node
(Case_Construction
);
830 Set_Next_End_Node
(Case_Construction
);
837 Start_New_Case_Construction
(In_Tree
, String_Type
);
841 while Token
= Tok_When
loop
843 if First_Case_Item
then
846 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
847 Set_First_Case_Item_Of
848 (Case_Construction
, In_Tree
, To
=> Current_Item
);
849 First_Case_Item
:= False;
854 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
855 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
856 Current_Item
:= Next_Item
;
859 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
865 if Token
= Tok_Others
then
868 -- Scan past "others"
872 Expect
(Tok_Arrow
, "`=>`");
873 Set_End_Of_Line
(Current_Item
);
874 Set_Previous_Line_Node
(Current_Item
);
876 -- Empty_Node in Field1 of a Case_Item indicates
877 -- the "when others =>" branch.
879 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
881 Parse_Declarative_Items
883 Declarations
=> First_Declarative_Item
,
884 In_Zone
=> In_Case_Construction
,
885 First_Attribute
=> First_Attribute
,
886 Current_Project
=> Current_Project
,
887 Current_Package
=> Current_Package
,
888 Packages_To_Check
=> Packages_To_Check
,
889 Is_Config_File
=> Is_Config_File
,
892 -- "when others =>" must be the last branch, so save the
893 -- Case_Item and exit
895 Set_First_Declarative_Item_Of
896 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
902 First_Choice
=> First_Choice
,
904 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
906 Expect
(Tok_Arrow
, "`=>`");
907 Set_End_Of_Line
(Current_Item
);
908 Set_Previous_Line_Node
(Current_Item
);
910 Parse_Declarative_Items
912 Declarations
=> First_Declarative_Item
,
913 In_Zone
=> In_Case_Construction
,
914 First_Attribute
=> First_Attribute
,
915 Current_Project
=> Current_Project
,
916 Current_Package
=> Current_Package
,
917 Packages_To_Check
=> Packages_To_Check
,
918 Is_Config_File
=> Is_Config_File
,
921 Set_First_Declarative_Item_Of
922 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
927 End_Case_Construction
928 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
929 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
932 Expect
(Tok_End
, "`END CASE`");
933 Remove_Next_End_Node
;
935 if Token
= Tok_End
then
941 Expect
(Tok_Case
, "CASE");
949 Expect
(Tok_Semicolon
, "`;`");
950 Set_Previous_End_Node
(Case_Construction
);
952 end Parse_Case_Construction
;
954 -----------------------------
955 -- Parse_Declarative_Items --
956 -----------------------------
958 procedure Parse_Declarative_Items
959 (In_Tree
: Project_Node_Tree_Ref
;
960 Declarations
: out Project_Node_Id
;
962 First_Attribute
: Attribute_Node_Id
;
963 Current_Project
: Project_Node_Id
;
964 Current_Package
: Project_Node_Id
;
965 Packages_To_Check
: String_List_Access
;
966 Is_Config_File
: Boolean;
967 Flags
: Processing_Flags
)
969 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
970 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
971 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
972 Item_Location
: Source_Ptr
:= No_Location
;
975 Declarations
:= Empty_Node
;
978 -- We are always positioned at the token that precedes the first
979 -- token of the declarative element. Scan past it.
983 Item_Location
:= Token_Ptr
;
986 when Tok_Identifier
=>
988 if In_Zone
= In_Case_Construction
then
990 -- Check if the variable has already been declared
993 The_Variable
: Project_Node_Id
:= Empty_Node
;
996 if Present
(Current_Package
) then
998 First_Variable_Of
(Current_Package
, In_Tree
);
999 elsif Present
(Current_Project
) then
1001 First_Variable_Of
(Current_Project
, In_Tree
);
1004 while Present
(The_Variable
)
1005 and then Name_Of
(The_Variable
, In_Tree
) /=
1008 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1011 -- It is an error to declare a variable in a case
1012 -- construction for the first time.
1014 if No
(The_Variable
) then
1017 "a variable cannot be declared " &
1018 "for the first time here",
1024 Parse_Variable_Declaration
1026 Current_Declaration
,
1027 Current_Project
=> Current_Project
,
1028 Current_Package
=> Current_Package
,
1031 Set_End_Of_Line
(Current_Declaration
);
1032 Set_Previous_Line_Node
(Current_Declaration
);
1036 Parse_Attribute_Declaration
1037 (In_Tree
=> In_Tree
,
1038 Attribute
=> Current_Declaration
,
1039 First_Attribute
=> First_Attribute
,
1040 Current_Project
=> Current_Project
,
1041 Current_Package
=> Current_Package
,
1042 Packages_To_Check
=> Packages_To_Check
,
1045 Set_End_Of_Line
(Current_Declaration
);
1046 Set_Previous_Line_Node
(Current_Declaration
);
1050 Scan
(In_Tree
); -- past "null"
1054 -- Package declaration
1056 if In_Zone
/= In_Project
then
1058 (Flags
, "a package cannot be declared here", Token_Ptr
);
1061 Parse_Package_Declaration
1062 (In_Tree
=> In_Tree
,
1063 Package_Declaration
=> Current_Declaration
,
1064 Current_Project
=> Current_Project
,
1065 Packages_To_Check
=> Packages_To_Check
,
1066 Is_Config_File
=> Is_Config_File
,
1069 Set_Previous_End_Node
(Current_Declaration
);
1073 -- Type String Declaration
1075 if In_Zone
/= In_Project
then
1077 "a string type cannot be declared here",
1081 Parse_String_Type_Declaration
1082 (In_Tree
=> In_Tree
,
1083 String_Type
=> Current_Declaration
,
1084 Current_Project
=> Current_Project
,
1087 Set_End_Of_Line
(Current_Declaration
);
1088 Set_Previous_Line_Node
(Current_Declaration
);
1092 -- Case construction
1094 Parse_Case_Construction
1095 (In_Tree
=> In_Tree
,
1096 Case_Construction
=> Current_Declaration
,
1097 First_Attribute
=> First_Attribute
,
1098 Current_Project
=> Current_Project
,
1099 Current_Package
=> Current_Package
,
1100 Packages_To_Check
=> Packages_To_Check
,
1101 Is_Config_File
=> Is_Config_File
,
1104 Set_Previous_End_Node
(Current_Declaration
);
1109 -- We are leaving Parse_Declarative_Items positioned
1110 -- at the first token after the list of declarative items.
1111 -- It could be "end" (for a project, a package declaration or
1112 -- a case construction) or "when" (for a case construction)
1116 Expect
(Tok_Semicolon
, "`;` after declarative items");
1118 -- Insert an N_Declarative_Item in the tree, but only if
1119 -- Current_Declaration is not an empty node.
1121 if Present
(Current_Declaration
) then
1122 if No
(Current_Declarative_Item
) then
1123 Current_Declarative_Item
:=
1124 Default_Project_Node
1125 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1126 Declarations
:= Current_Declarative_Item
;
1129 Next_Declarative_Item
:=
1130 Default_Project_Node
1131 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1132 Set_Next_Declarative_Item
1133 (Current_Declarative_Item
, In_Tree
,
1134 To
=> Next_Declarative_Item
);
1135 Current_Declarative_Item
:= Next_Declarative_Item
;
1138 Set_Current_Item_Node
1139 (Current_Declarative_Item
, In_Tree
,
1140 To
=> Current_Declaration
);
1142 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1145 end Parse_Declarative_Items
;
1147 -------------------------------
1148 -- Parse_Package_Declaration --
1149 -------------------------------
1151 procedure Parse_Package_Declaration
1152 (In_Tree
: Project_Node_Tree_Ref
;
1153 Package_Declaration
: out Project_Node_Id
;
1154 Current_Project
: Project_Node_Id
;
1155 Packages_To_Check
: String_List_Access
;
1156 Is_Config_File
: Boolean;
1157 Flags
: Processing_Flags
)
1159 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1160 Current_Package
: Package_Node_Id
:= Empty_Package
;
1161 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1162 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1163 Renaming
: Boolean := False;
1164 Extending
: Boolean := False;
1167 Package_Declaration
:=
1168 Default_Project_Node
1169 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1170 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1172 -- Scan past "package"
1175 Expect
(Tok_Identifier
, "identifier");
1177 if Token
= Tok_Identifier
then
1178 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1180 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1182 if Current_Package
= Empty_Package
then
1183 if not Quiet_Output
then
1185 List
: constant Strings
.String_List
:= Package_Name_List
;
1187 Name
: constant String := Get_Name_String
(Token_Name
);
1190 -- Check for possible misspelling of a known package name
1194 if Index
>= List
'Last then
1201 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1202 (Name
, List
(Index
).all);
1205 -- Issue warning(s) in verbose mode or when a possible
1206 -- misspelling has been found.
1208 if Verbose_Mode
or else Index
/= 0 then
1212 (Name_Of
(Package_Declaration
, In_Tree
)) &
1213 """ is not a known package name",
1218 Error_Msg
-- CODEFIX
1220 "\?possible misspelling of """ &
1221 List
(Index
).all & """", Token_Ptr
);
1226 -- Set the package declaration to "ignored" so that it is not
1227 -- processed by Prj.Proc.Process.
1229 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1231 -- Add the unknown package in the list of packages
1233 Add_Unknown_Package
(Token_Name
, Current_Package
);
1235 elsif Current_Package
= Unknown_Package
then
1237 -- Set the package declaration to "ignored" so that it is not
1238 -- processed by Prj.Proc.Process.
1240 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1243 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1247 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1250 Current
: Project_Node_Id
:=
1251 First_Package_Of
(Current_Project
, In_Tree
);
1254 while Present
(Current
)
1255 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1257 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1260 if Present
(Current
) then
1264 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1265 """ is declared twice in the same project",
1269 -- Add the package to the project list
1271 Set_Next_Package_In_Project
1272 (Package_Declaration
, In_Tree
,
1273 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1274 Set_First_Package_Of
1275 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1279 -- Scan past the package name
1284 Check_Package_Allowed
1285 (In_Tree
, Current_Project
, Package_Declaration
, Flags
);
1287 if Token
= Tok_Renames
then
1289 elsif Token
= Tok_Extends
then
1293 if Renaming
or else Extending
then
1294 if Is_Config_File
then
1297 "no package rename or extension in configuration projects",
1301 -- Scan past "renames" or "extends"
1305 Expect
(Tok_Identifier
, "identifier");
1307 if Token
= Tok_Identifier
then
1309 Project_Name
: constant Name_Id
:= Token_Name
;
1311 Clause
: Project_Node_Id
:=
1312 First_With_Clause_Of
(Current_Project
, In_Tree
);
1313 The_Project
: Project_Node_Id
:= Empty_Node
;
1314 Extended
: constant Project_Node_Id
:=
1316 (Project_Declaration_Of
1317 (Current_Project
, In_Tree
),
1320 while Present
(Clause
) loop
1321 -- Only non limited imported projects may be used in a
1322 -- renames declaration.
1325 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1326 exit when Present
(The_Project
)
1327 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1328 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1332 -- As we have not found the project in the imports, we check
1333 -- if it's the name of an eventual extended project.
1335 if Present
(Extended
)
1336 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1338 Set_Project_Of_Renamed_Package_Of
1339 (Package_Declaration
, In_Tree
, To
=> Extended
);
1341 Error_Msg_Name_1
:= Project_Name
;
1344 "% is not an imported or extended project", Token_Ptr
);
1347 Set_Project_Of_Renamed_Package_Of
1348 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1353 Expect
(Tok_Dot
, "`.`");
1355 if Token
= Tok_Dot
then
1357 Expect
(Tok_Identifier
, "identifier");
1359 if Token
= Tok_Identifier
then
1360 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1361 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1363 Present
(Project_Of_Renamed_Package_Of
1364 (Package_Declaration
, In_Tree
))
1367 Current
: Project_Node_Id
:=
1369 (Project_Of_Renamed_Package_Of
1370 (Package_Declaration
, In_Tree
),
1374 while Present
(Current
)
1375 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1378 Next_Package_In_Project
(Current
, In_Tree
);
1381 if No
(Current
) then
1384 Get_Name_String
(Token_Name
) &
1385 """ is not a package declared by the project",
1398 Expect
(Tok_Semicolon
, "`;`");
1399 Set_End_Of_Line
(Package_Declaration
);
1400 Set_Previous_Line_Node
(Package_Declaration
);
1402 elsif Token
= Tok_Is
then
1403 Set_End_Of_Line
(Package_Declaration
);
1404 Set_Previous_Line_Node
(Package_Declaration
);
1405 Set_Next_End_Node
(Package_Declaration
);
1407 Parse_Declarative_Items
1408 (In_Tree
=> In_Tree
,
1409 Declarations
=> First_Declarative_Item
,
1410 In_Zone
=> In_Package
,
1411 First_Attribute
=> First_Attribute
,
1412 Current_Project
=> Current_Project
,
1413 Current_Package
=> Package_Declaration
,
1414 Packages_To_Check
=> Packages_To_Check
,
1415 Is_Config_File
=> Is_Config_File
,
1418 Set_First_Declarative_Item_Of
1419 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1421 Expect
(Tok_End
, "END");
1423 if Token
= Tok_End
then
1430 -- We should have the name of the package after "end"
1432 Expect
(Tok_Identifier
, "identifier");
1434 if Token
= Tok_Identifier
1435 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1436 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1438 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1439 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1442 if Token
/= Tok_Semicolon
then
1444 -- Scan past the package name
1449 Expect
(Tok_Semicolon
, "`;`");
1450 Remove_Next_End_Node
;
1453 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1456 end Parse_Package_Declaration
;
1458 -----------------------------------
1459 -- Parse_String_Type_Declaration --
1460 -----------------------------------
1462 procedure Parse_String_Type_Declaration
1463 (In_Tree
: Project_Node_Tree_Ref
;
1464 String_Type
: out Project_Node_Id
;
1465 Current_Project
: Project_Node_Id
;
1466 Flags
: Processing_Flags
)
1468 Current
: Project_Node_Id
:= Empty_Node
;
1469 First_String
: Project_Node_Id
:= Empty_Node
;
1473 Default_Project_Node
1474 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1476 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1482 Expect
(Tok_Identifier
, "identifier");
1484 if Token
= Tok_Identifier
then
1485 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1487 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1488 while Present
(Current
)
1490 Name_Of
(Current
, In_Tree
) /= Token_Name
1492 Current
:= Next_String_Type
(Current
, In_Tree
);
1495 if Present
(Current
) then
1497 "duplicate string type name """ &
1498 Get_Name_String
(Token_Name
) &
1502 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1503 while Present
(Current
)
1504 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1506 Current
:= Next_Variable
(Current
, In_Tree
);
1509 if Present
(Current
) then
1512 Get_Name_String
(Token_Name
) &
1513 """ is already a variable name", Token_Ptr
);
1515 Set_Next_String_Type
1516 (String_Type
, In_Tree
,
1517 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1518 Set_First_String_Type_Of
1519 (Current_Project
, In_Tree
, To
=> String_Type
);
1523 -- Scan past the name
1528 Expect
(Tok_Is
, "IS");
1530 if Token
= Tok_Is
then
1534 Expect
(Tok_Left_Paren
, "`(`");
1536 if Token
= Tok_Left_Paren
then
1540 Parse_String_Type_List
1541 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1542 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1544 Expect
(Tok_Right_Paren
, "`)`");
1546 if Token
= Tok_Right_Paren
then
1550 end Parse_String_Type_Declaration
;
1552 --------------------------------
1553 -- Parse_Variable_Declaration --
1554 --------------------------------
1556 procedure Parse_Variable_Declaration
1557 (In_Tree
: Project_Node_Tree_Ref
;
1558 Variable
: out Project_Node_Id
;
1559 Current_Project
: Project_Node_Id
;
1560 Current_Package
: Project_Node_Id
;
1561 Flags
: Processing_Flags
)
1563 Expression_Location
: Source_Ptr
;
1564 String_Type_Name
: Name_Id
:= No_Name
;
1565 Project_String_Type_Name
: Name_Id
:= No_Name
;
1566 Type_Location
: Source_Ptr
:= No_Location
;
1567 Project_Location
: Source_Ptr
:= No_Location
;
1568 Expression
: Project_Node_Id
:= Empty_Node
;
1569 Variable_Name
: constant Name_Id
:= Token_Name
;
1570 OK
: Boolean := True;
1574 Default_Project_Node
1575 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1576 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1577 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1579 -- Scan past the variable name
1583 if Token
= Tok_Colon
then
1585 -- Typed string variable declaration
1588 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1589 Expect
(Tok_Identifier
, "identifier");
1591 OK
:= Token
= Tok_Identifier
;
1594 String_Type_Name
:= Token_Name
;
1595 Type_Location
:= Token_Ptr
;
1598 if Token
= Tok_Dot
then
1599 Project_String_Type_Name
:= String_Type_Name
;
1600 Project_Location
:= Type_Location
;
1602 -- Scan past the dot
1605 Expect
(Tok_Identifier
, "identifier");
1607 if Token
= Tok_Identifier
then
1608 String_Type_Name
:= Token_Name
;
1609 Type_Location
:= Token_Ptr
;
1618 Proj
: Project_Node_Id
:= Current_Project
;
1619 Current
: Project_Node_Id
:= Empty_Node
;
1622 if Project_String_Type_Name
/= No_Name
then
1624 The_Project_Name_And_Node
: constant
1625 Tree_Private_Part
.Project_Name_And_Node
:=
1626 Tree_Private_Part
.Projects_Htable
.Get
1627 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1629 use Tree_Private_Part
;
1632 if The_Project_Name_And_Node
=
1633 Tree_Private_Part
.No_Project_Name_And_Node
1636 "unknown project """ &
1638 (Project_String_Type_Name
) &
1641 Current
:= Empty_Node
;
1644 First_String_Type_Of
1645 (The_Project_Name_And_Node
.Node
, In_Tree
);
1649 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1651 Current
:= Next_String_Type
(Current
, In_Tree
);
1657 -- Look for a string type with the correct name in this
1658 -- project or in any of its ancestors.
1662 First_String_Type_Of
(Proj
, In_Tree
);
1666 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1668 Current
:= Next_String_Type
(Current
, In_Tree
);
1671 exit when Present
(Current
);
1673 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1674 exit when No
(Proj
);
1678 if No
(Current
) then
1680 "unknown string type """ &
1681 Get_Name_String
(String_Type_Name
) &
1688 (Variable
, In_Tree
, To
=> Current
);
1695 Expect
(Tok_Colon_Equal
, "`:=`");
1697 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1699 if Token
= Tok_Colon_Equal
then
1703 -- Get the single string or string list value
1705 Expression_Location
:= Token_Ptr
;
1708 (In_Tree
=> In_Tree
,
1709 Expression
=> Expression
,
1711 Current_Project
=> Current_Project
,
1712 Current_Package
=> Current_Package
,
1713 Optional_Index
=> False);
1714 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1716 if Present
(Expression
) then
1717 -- A typed string must have a single string value, not a list
1719 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1720 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1724 "expression must be a single string", Expression_Location
);
1727 Set_Expression_Kind_Of
1729 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1734 The_Variable
: Project_Node_Id
:= Empty_Node
;
1737 if Present
(Current_Package
) then
1738 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1739 elsif Present
(Current_Project
) then
1740 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1743 while Present
(The_Variable
)
1744 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1746 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1749 if No
(The_Variable
) then
1750 if Present
(Current_Package
) then
1753 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1754 Set_First_Variable_Of
1755 (Current_Package
, In_Tree
, To
=> Variable
);
1757 elsif Present
(Current_Project
) then
1760 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1761 Set_First_Variable_Of
1762 (Current_Project
, In_Tree
, To
=> Variable
);
1766 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1767 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1770 Set_Expression_Kind_Of
1771 (The_Variable
, In_Tree
,
1772 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1775 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1776 Expression_Kind_Of
(Variable
, In_Tree
)
1779 "wrong expression kind for variable """ &
1781 (Name_Of
(The_Variable
, In_Tree
)) &
1783 Expression_Location
);
1790 end Parse_Variable_Declaration
;