1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2010, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Err_Vars
; use Err_Vars
;
28 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
29 with GNAT
.Spelling_Checker
; use GNAT
.Spelling_Checker
;
32 with Prj
.Attr
; use Prj
.Attr
;
33 with Prj
.Attr
.PM
; use Prj
.Attr
.PM
;
34 with Prj
.Err
; use Prj
.Err
;
35 with Prj
.Strt
; use Prj
.Strt
;
36 with Prj
.Tree
; use Prj
.Tree
;
38 with Uintp
; use Uintp
;
42 package body Prj
.Dect
is
46 type Zone
is (In_Project
, In_Package
, In_Case_Construction
);
47 -- Used to indicate if we are parsing a package (In_Package),
48 -- a case construction (In_Case_Construction) or none of those two
51 procedure Rename_Obsolescent_Attributes
52 (In_Tree
: Project_Node_Tree_Ref
;
53 Attribute
: Project_Node_Id
;
54 Current_Package
: Project_Node_Id
);
55 -- Rename obsolescent attributes in the tree.
56 -- When the attribute has been renamed since its initial introduction in
57 -- the design of projects, we replace the old name in the tree with the
58 -- new name, so that the code does not have to check both names forever.
60 procedure Check_Attribute_Allowed
61 (In_Tree
: Project_Node_Tree_Ref
;
62 Project
: Project_Node_Id
;
63 Attribute
: Project_Node_Id
;
64 Flags
: Processing_Flags
);
65 -- Chech whether the attribute is valid in this project.
66 -- In particular, depending on the type of project (qualifier), some
67 -- attributes might be disabled.
69 procedure Check_Package_Allowed
70 (In_Tree
: Project_Node_Tree_Ref
;
71 Project
: Project_Node_Id
;
72 Current_Package
: Project_Node_Id
;
73 Flags
: Processing_Flags
);
74 -- Check whether the package is valid in this project
76 procedure Parse_Attribute_Declaration
77 (In_Tree
: Project_Node_Tree_Ref
;
78 Attribute
: out Project_Node_Id
;
79 First_Attribute
: Attribute_Node_Id
;
80 Current_Project
: Project_Node_Id
;
81 Current_Package
: Project_Node_Id
;
82 Packages_To_Check
: String_List_Access
;
83 Flags
: Processing_Flags
);
84 -- Parse an attribute declaration
86 procedure Parse_Case_Construction
87 (In_Tree
: Project_Node_Tree_Ref
;
88 Case_Construction
: out Project_Node_Id
;
89 First_Attribute
: Attribute_Node_Id
;
90 Current_Project
: Project_Node_Id
;
91 Current_Package
: Project_Node_Id
;
92 Packages_To_Check
: String_List_Access
;
93 Is_Config_File
: Boolean;
94 Flags
: Processing_Flags
);
95 -- Parse a case construction
97 procedure Parse_Declarative_Items
98 (In_Tree
: Project_Node_Tree_Ref
;
99 Declarations
: out Project_Node_Id
;
101 First_Attribute
: Attribute_Node_Id
;
102 Current_Project
: Project_Node_Id
;
103 Current_Package
: Project_Node_Id
;
104 Packages_To_Check
: String_List_Access
;
105 Is_Config_File
: Boolean;
106 Flags
: Processing_Flags
);
107 -- Parse declarative items. Depending on In_Zone, some declarative items
108 -- may be forbidden. Is_Config_File should be set to True if the project
109 -- represents a config file (.cgpr) since some specific checks apply.
111 procedure Parse_Package_Declaration
112 (In_Tree
: Project_Node_Tree_Ref
;
113 Package_Declaration
: out Project_Node_Id
;
114 Current_Project
: Project_Node_Id
;
115 Packages_To_Check
: String_List_Access
;
116 Is_Config_File
: Boolean;
117 Flags
: Processing_Flags
);
118 -- Parse a package declaration.
119 -- Is_Config_File should be set to True if the project represents a config
120 -- file (.cgpr) since some specific checks apply.
122 procedure Parse_String_Type_Declaration
123 (In_Tree
: Project_Node_Tree_Ref
;
124 String_Type
: out Project_Node_Id
;
125 Current_Project
: Project_Node_Id
;
126 Flags
: Processing_Flags
);
127 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
129 procedure Parse_Variable_Declaration
130 (In_Tree
: Project_Node_Tree_Ref
;
131 Variable
: out Project_Node_Id
;
132 Current_Project
: Project_Node_Id
;
133 Current_Package
: Project_Node_Id
;
134 Flags
: Processing_Flags
);
135 -- Parse a variable assignment
136 -- <variable_Name> := <expression>; OR
137 -- <variable_Name> : <string_type_Name> := <string_expression>;
144 (In_Tree
: Project_Node_Tree_Ref
;
145 Declarations
: out Project_Node_Id
;
146 Current_Project
: Project_Node_Id
;
147 Extends
: Project_Node_Id
;
148 Packages_To_Check
: String_List_Access
;
149 Is_Config_File
: Boolean;
150 Flags
: Processing_Flags
)
152 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
157 (Of_Kind
=> N_Project_Declaration
, In_Tree
=> In_Tree
);
158 Set_Location_Of
(Declarations
, In_Tree
, To
=> Token_Ptr
);
159 Set_Extended_Project_Of
(Declarations
, In_Tree
, To
=> Extends
);
160 Set_Project_Declaration_Of
(Current_Project
, In_Tree
, Declarations
);
161 Parse_Declarative_Items
162 (Declarations
=> First_Declarative_Item
,
164 In_Zone
=> In_Project
,
165 First_Attribute
=> Prj
.Attr
.Attribute_First
,
166 Current_Project
=> Current_Project
,
167 Current_Package
=> Empty_Node
,
168 Packages_To_Check
=> Packages_To_Check
,
169 Is_Config_File
=> Is_Config_File
,
171 Set_First_Declarative_Item_Of
172 (Declarations
, In_Tree
, To
=> First_Declarative_Item
);
175 -----------------------------------
176 -- Rename_Obsolescent_Attributes --
177 -----------------------------------
179 procedure Rename_Obsolescent_Attributes
180 (In_Tree
: Project_Node_Tree_Ref
;
181 Attribute
: Project_Node_Id
;
182 Current_Package
: Project_Node_Id
)
185 if Present
(Current_Package
)
186 and then Expression_Kind_Of
(Current_Package
, In_Tree
) /= Ignored
188 case Name_Of
(Attribute
, In_Tree
) is
189 when Snames
.Name_Specification
=>
190 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec
);
192 when Snames
.Name_Specification_Suffix
=>
193 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Spec_Suffix
);
195 when Snames
.Name_Implementation
=>
196 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body
);
198 when Snames
.Name_Implementation_Suffix
=>
199 Set_Name_Of
(Attribute
, In_Tree
, To
=> Snames
.Name_Body_Suffix
);
205 end Rename_Obsolescent_Attributes
;
207 ---------------------------
208 -- Check_Package_Allowed --
209 ---------------------------
211 procedure Check_Package_Allowed
212 (In_Tree
: Project_Node_Tree_Ref
;
213 Project
: Project_Node_Id
;
214 Current_Package
: Project_Node_Id
;
215 Flags
: Processing_Flags
)
217 Qualif
: constant Project_Qualifier
:=
218 Project_Qualifier_Of
(Project
, In_Tree
);
219 Name
: constant Name_Id
:= Name_Of
(Current_Package
, In_Tree
);
221 if Qualif
= Aggregate
222 and then Name
/= Snames
.Name_Builder
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
);
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 Error_Msg_Name_1
:= Name
;
264 "%% is not valid in aggregate projects",
265 Location_Of
(Attribute
, In_Tree
));
269 if Name
= Snames
.Name_Project_Files
270 or else Name
= Snames
.Name_Project_Path
271 or else Name
= Snames
.Name_External
273 Error_Msg_Name_1
:= Name
;
276 "%% is only valid in aggregate projects",
277 Location_Of
(Attribute
, In_Tree
));
280 end Check_Attribute_Allowed
;
282 ---------------------------------
283 -- Parse_Attribute_Declaration --
284 ---------------------------------
286 procedure Parse_Attribute_Declaration
287 (In_Tree
: Project_Node_Tree_Ref
;
288 Attribute
: out Project_Node_Id
;
289 First_Attribute
: Attribute_Node_Id
;
290 Current_Project
: Project_Node_Id
;
291 Current_Package
: Project_Node_Id
;
292 Packages_To_Check
: String_List_Access
;
293 Flags
: Processing_Flags
)
295 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
296 Full_Associative_Array
: Boolean := False;
297 Attribute_Name
: Name_Id
:= No_Name
;
298 Optional_Index
: Boolean := False;
299 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
301 procedure Process_Attribute_Name
;
302 -- Read the name of the attribute, and check its type
304 procedure Process_Associative_Array_Index
;
305 -- Read the index of the associative array and check its validity
307 ----------------------------
308 -- Process_Attribute_Name --
309 ----------------------------
311 procedure Process_Attribute_Name
is
315 Attribute_Name
:= Token_Name
;
316 Set_Name_Of
(Attribute
, In_Tree
, To
=> Attribute_Name
);
317 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
319 -- Find the attribute
322 Attribute_Node_Id_Of
(Attribute_Name
, First_Attribute
);
324 -- If the attribute cannot be found, create the attribute if inside
325 -- an unknown package.
327 if Current_Attribute
= Empty_Attribute
then
328 if Present
(Current_Package
)
329 and then Expression_Kind_Of
(Current_Package
, In_Tree
) = Ignored
331 Pkg_Id
:= Package_Id_Of
(Current_Package
, In_Tree
);
332 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
335 -- If not a valid attribute name, issue an error if inside
336 -- a package that need to be checked.
338 Ignore
:= Present
(Current_Package
) and then
339 Packages_To_Check
/= All_Packages
;
343 -- Check that we are not in a package to check
345 Get_Name_String
(Name_Of
(Current_Package
, In_Tree
));
347 for Index
in Packages_To_Check
'Range loop
348 if Name_Buffer
(1 .. Name_Len
) =
349 Packages_To_Check
(Index
).all
358 Error_Msg_Name_1
:= Token_Name
;
359 Error_Msg
(Flags
, "undefined attribute %%", Token_Ptr
);
363 -- Set, if appropriate the index case insensitivity flag
366 if Is_Read_Only
(Current_Attribute
) then
367 Error_Msg_Name_1
:= Token_Name
;
369 (Flags
, "read-only attribute %% cannot be given a value",
373 if Attribute_Kind_Of
(Current_Attribute
) in
374 All_Case_Insensitive_Associative_Array
376 Set_Case_Insensitive
(Attribute
, In_Tree
, To
=> True);
380 Scan
(In_Tree
); -- past the attribute name
382 -- Set the expression kind of the attribute
384 if Current_Attribute
/= Empty_Attribute
then
385 Set_Expression_Kind_Of
386 (Attribute
, In_Tree
, To
=> Variable_Kind_Of
(Current_Attribute
));
387 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
389 end Process_Attribute_Name
;
391 -------------------------------------
392 -- Process_Associative_Array_Index --
393 -------------------------------------
395 procedure Process_Associative_Array_Index
is
397 -- If the attribute is not an associative array attribute, report
398 -- an error. If this information is still unknown, set the kind
399 -- to Associative_Array.
401 if Current_Attribute
/= Empty_Attribute
402 and then Attribute_Kind_Of
(Current_Attribute
) = Single
406 Get_Name_String
(Attribute_Name_Of
(Current_Attribute
))
407 & """ cannot be an associative array",
408 Location_Of
(Attribute
, In_Tree
));
410 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
411 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
414 Scan
(In_Tree
); -- past the left parenthesis
416 if Others_Allowed_For
(Current_Attribute
)
417 and then Token
= Tok_Others
419 Set_Associative_Array_Index_Of
420 (Attribute
, In_Tree
, All_Other_Names
);
421 Scan
(In_Tree
); -- past others
424 if Others_Allowed_For
(Current_Attribute
) then
425 Expect
(Tok_String_Literal
, "literal string or others");
427 Expect
(Tok_String_Literal
, "literal string");
430 if Token
= Tok_String_Literal
then
431 Get_Name_String
(Token_Name
);
433 if Case_Insensitive
(Attribute
, In_Tree
) then
434 To_Lower
(Name_Buffer
(1 .. Name_Len
));
437 Set_Associative_Array_Index_Of
(Attribute
, In_Tree
, Name_Find
);
438 Scan
(In_Tree
); -- past the literal string index
440 if Token
= Tok_At
then
441 case Attribute_Kind_Of
(Current_Attribute
) is
442 when Optional_Index_Associative_Array |
443 Optional_Index_Case_Insensitive_Associative_Array
=>
445 Expect
(Tok_Integer_Literal
, "integer literal");
447 if Token
= Tok_Integer_Literal
then
449 -- Set the source index value from given literal
452 Index
: constant Int
:=
453 UI_To_Int
(Int_Literal_Value
);
457 (Flags
, "index cannot be zero", Token_Ptr
);
460 (Attribute
, In_Tree
, To
=> Index
);
468 Error_Msg
(Flags
, "index not allowed here", Token_Ptr
);
471 if Token
= Tok_Integer_Literal
then
479 Expect
(Tok_Right_Paren
, "`)`");
481 if Token
= Tok_Right_Paren
then
482 Scan
(In_Tree
); -- past the right parenthesis
484 end Process_Associative_Array_Index
;
489 (Of_Kind
=> N_Attribute_Declaration
, In_Tree
=> In_Tree
);
490 Set_Location_Of
(Attribute
, In_Tree
, To
=> Token_Ptr
);
491 Set_Previous_Line_Node
(Attribute
);
497 -- Body may be an attribute name
499 if Token
= Tok_Body
then
500 Token
:= Tok_Identifier
;
501 Token_Name
:= Snames
.Name_Body
;
504 Expect
(Tok_Identifier
, "identifier");
505 Process_Attribute_Name
;
506 Rename_Obsolescent_Attributes
(In_Tree
, Attribute
, Current_Package
);
507 Check_Attribute_Allowed
(In_Tree
, Current_Project
, Attribute
, Flags
);
509 -- Associative array attributes
511 if Token
= Tok_Left_Paren
then
512 Process_Associative_Array_Index
;
515 -- If it is an associative array attribute and there are no left
516 -- parenthesis, then this is a full associative array declaration.
517 -- Flag it as such for later processing of its value.
519 if Current_Attribute
/= Empty_Attribute
521 Attribute_Kind_Of
(Current_Attribute
) /= Single
523 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
524 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
527 Full_Associative_Array
:= True;
532 Expect
(Tok_Use
, "USE");
534 if Token
= Tok_Use
then
537 if Full_Associative_Array
then
539 -- Expect <project>'<same_attribute_name>, or
540 -- <project>.<same_package_name>'<same_attribute_name>
543 The_Project
: Project_Node_Id
:= Empty_Node
;
544 -- The node of the project where the associative array is
547 The_Package
: Project_Node_Id
:= Empty_Node
;
548 -- The node of the package where the associative array is
551 Project_Name
: Name_Id
:= No_Name
;
552 -- The name of the project where the associative array is
555 Location
: Source_Ptr
:= No_Location
;
556 -- The location of the project name
559 Expect
(Tok_Identifier
, "identifier");
561 if Token
= Tok_Identifier
then
562 Location
:= Token_Ptr
;
564 -- Find the project node in the imported project or
565 -- in the project being extended.
567 The_Project
:= Imported_Or_Extended_Project_Of
568 (Current_Project
, In_Tree
, Token_Name
);
570 if No
(The_Project
) then
571 Error_Msg
(Flags
, "unknown project", Location
);
572 Scan
(In_Tree
); -- past the project name
575 Project_Name
:= Token_Name
;
576 Scan
(In_Tree
); -- past the project name
578 -- If this is inside a package, a dot followed by the
579 -- name of the package must followed the project name.
581 if Present
(Current_Package
) then
582 Expect
(Tok_Dot
, "`.`");
584 if Token
/= Tok_Dot
then
585 The_Project
:= Empty_Node
;
588 Scan
(In_Tree
); -- past the dot
589 Expect
(Tok_Identifier
, "identifier");
591 if Token
/= Tok_Identifier
then
592 The_Project
:= Empty_Node
;
594 -- If it is not the same package name, issue error
597 Token_Name
/= Name_Of
(Current_Package
, In_Tree
)
599 The_Project
:= Empty_Node
;
601 (Flags
, "not the same package as " &
603 (Name_Of
(Current_Package
, In_Tree
)),
608 First_Package_Of
(The_Project
, In_Tree
);
610 -- Look for the package node
612 while Present
(The_Package
)
614 Name_Of
(The_Package
, In_Tree
) /= Token_Name
617 Next_Package_In_Project
618 (The_Package
, In_Tree
);
621 -- If the package cannot be found in the
622 -- project, issue an error.
624 if No
(The_Package
) then
625 The_Project
:= Empty_Node
;
626 Error_Msg_Name_2
:= Project_Name
;
627 Error_Msg_Name_1
:= Token_Name
;
630 "package % not declared in project %",
634 Scan
(In_Tree
); -- past the package name
641 if Present
(The_Project
) then
643 -- Looking for '<same attribute name>
645 Expect
(Tok_Apostrophe
, "`''`");
647 if Token
/= Tok_Apostrophe
then
648 The_Project
:= Empty_Node
;
651 Scan
(In_Tree
); -- past the apostrophe
652 Expect
(Tok_Identifier
, "identifier");
654 if Token
/= Tok_Identifier
then
655 The_Project
:= Empty_Node
;
658 -- If it is not the same attribute name, issue error
660 if Token_Name
/= Attribute_Name
then
661 The_Project
:= Empty_Node
;
662 Error_Msg_Name_1
:= Attribute_Name
;
664 (Flags
, "invalid name, should be %", Token_Ptr
);
667 Scan
(In_Tree
); -- past the attribute name
672 if No
(The_Project
) then
674 -- If there were any problem, set the attribute id to null,
675 -- so that the node will not be recorded.
677 Current_Attribute
:= Empty_Attribute
;
680 -- Set the appropriate field in the node.
681 -- Note that the index and the expression are nil. This
682 -- characterizes full associative array attribute
685 Set_Associative_Project_Of
(Attribute
, In_Tree
, The_Project
);
686 Set_Associative_Package_Of
(Attribute
, In_Tree
, The_Package
);
690 -- Other attribute declarations (not full associative array)
694 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
695 -- The location of the first token of the expression
697 Expression
: Project_Node_Id
:= Empty_Node
;
698 -- The expression, value for the attribute declaration
701 -- Get the expression value and set it in the attribute node
705 Expression
=> Expression
,
707 Current_Project
=> Current_Project
,
708 Current_Package
=> Current_Package
,
709 Optional_Index
=> Optional_Index
);
710 Set_Expression_Of
(Attribute
, In_Tree
, To
=> Expression
);
712 -- If the expression is legal, but not of the right kind
713 -- for the attribute, issue an error.
715 if Current_Attribute
/= Empty_Attribute
716 and then Present
(Expression
)
717 and then Variable_Kind_Of
(Current_Attribute
) /=
718 Expression_Kind_Of
(Expression
, In_Tree
)
720 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
723 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
727 (Flags
, "wrong expression kind for attribute """ &
729 (Attribute_Name_Of
(Current_Attribute
)) &
731 Expression_Location
);
738 -- If the attribute was not recognized, return an empty node.
739 -- It may be that it is not in a package to check, and the node will
740 -- not be added to the tree.
742 if Current_Attribute
= Empty_Attribute
then
743 Attribute
:= Empty_Node
;
746 Set_End_Of_Line
(Attribute
);
747 Set_Previous_Line_Node
(Attribute
);
748 end Parse_Attribute_Declaration
;
750 -----------------------------
751 -- Parse_Case_Construction --
752 -----------------------------
754 procedure Parse_Case_Construction
755 (In_Tree
: Project_Node_Tree_Ref
;
756 Case_Construction
: out Project_Node_Id
;
757 First_Attribute
: Attribute_Node_Id
;
758 Current_Project
: Project_Node_Id
;
759 Current_Package
: Project_Node_Id
;
760 Packages_To_Check
: String_List_Access
;
761 Is_Config_File
: Boolean;
762 Flags
: Processing_Flags
)
764 Current_Item
: Project_Node_Id
:= Empty_Node
;
765 Next_Item
: Project_Node_Id
:= Empty_Node
;
766 First_Case_Item
: Boolean := True;
768 Variable_Location
: Source_Ptr
:= No_Location
;
770 String_Type
: Project_Node_Id
:= Empty_Node
;
772 Case_Variable
: Project_Node_Id
:= Empty_Node
;
774 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
776 First_Choice
: Project_Node_Id
:= Empty_Node
;
778 When_Others
: Boolean := False;
779 -- Set to True when there is a "when others =>" clause
784 (Of_Kind
=> N_Case_Construction
, In_Tree
=> In_Tree
);
785 Set_Location_Of
(Case_Construction
, In_Tree
, To
=> Token_Ptr
);
791 -- Get the switch variable
793 Expect
(Tok_Identifier
, "identifier");
795 if Token
= Tok_Identifier
then
796 Variable_Location
:= Token_Ptr
;
797 Parse_Variable_Reference
799 Variable
=> Case_Variable
,
801 Current_Project
=> Current_Project
,
802 Current_Package
=> Current_Package
);
803 Set_Case_Variable_Reference_Of
804 (Case_Construction
, In_Tree
, To
=> Case_Variable
);
807 if Token
/= Tok_Is
then
812 if Present
(Case_Variable
) then
813 String_Type
:= String_Type_Of
(Case_Variable
, In_Tree
);
815 if No
(String_Type
) then
818 Get_Name_String
(Name_Of
(Case_Variable
, In_Tree
)) &
824 Expect
(Tok_Is
, "IS");
826 if Token
= Tok_Is
then
827 Set_End_Of_Line
(Case_Construction
);
828 Set_Previous_Line_Node
(Case_Construction
);
829 Set_Next_End_Node
(Case_Construction
);
836 Start_New_Case_Construction
(In_Tree
, String_Type
);
840 while Token
= Tok_When
loop
842 if First_Case_Item
then
845 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
846 Set_First_Case_Item_Of
847 (Case_Construction
, In_Tree
, To
=> Current_Item
);
848 First_Case_Item
:= False;
853 (Of_Kind
=> N_Case_Item
, In_Tree
=> In_Tree
);
854 Set_Next_Case_Item
(Current_Item
, In_Tree
, To
=> Next_Item
);
855 Current_Item
:= Next_Item
;
858 Set_Location_Of
(Current_Item
, In_Tree
, To
=> Token_Ptr
);
864 if Token
= Tok_Others
then
867 -- Scan past "others"
871 Expect
(Tok_Arrow
, "`=>`");
872 Set_End_Of_Line
(Current_Item
);
873 Set_Previous_Line_Node
(Current_Item
);
875 -- Empty_Node in Field1 of a Case_Item indicates
876 -- the "when others =>" branch.
878 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> Empty_Node
);
880 Parse_Declarative_Items
882 Declarations
=> First_Declarative_Item
,
883 In_Zone
=> In_Case_Construction
,
884 First_Attribute
=> First_Attribute
,
885 Current_Project
=> Current_Project
,
886 Current_Package
=> Current_Package
,
887 Packages_To_Check
=> Packages_To_Check
,
888 Is_Config_File
=> Is_Config_File
,
891 -- "when others =>" must be the last branch, so save the
892 -- Case_Item and exit
894 Set_First_Declarative_Item_Of
895 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
901 First_Choice
=> First_Choice
,
903 Set_First_Choice_Of
(Current_Item
, In_Tree
, To
=> First_Choice
);
905 Expect
(Tok_Arrow
, "`=>`");
906 Set_End_Of_Line
(Current_Item
);
907 Set_Previous_Line_Node
(Current_Item
);
909 Parse_Declarative_Items
911 Declarations
=> First_Declarative_Item
,
912 In_Zone
=> In_Case_Construction
,
913 First_Attribute
=> First_Attribute
,
914 Current_Project
=> Current_Project
,
915 Current_Package
=> Current_Package
,
916 Packages_To_Check
=> Packages_To_Check
,
917 Is_Config_File
=> Is_Config_File
,
920 Set_First_Declarative_Item_Of
921 (Current_Item
, In_Tree
, To
=> First_Declarative_Item
);
926 End_Case_Construction
927 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
928 Case_Location
=> Location_Of
(Case_Construction
, In_Tree
),
931 Expect
(Tok_End
, "`END CASE`");
932 Remove_Next_End_Node
;
934 if Token
= Tok_End
then
940 Expect
(Tok_Case
, "CASE");
948 Expect
(Tok_Semicolon
, "`;`");
949 Set_Previous_End_Node
(Case_Construction
);
951 end Parse_Case_Construction
;
953 -----------------------------
954 -- Parse_Declarative_Items --
955 -----------------------------
957 procedure Parse_Declarative_Items
958 (In_Tree
: Project_Node_Tree_Ref
;
959 Declarations
: out Project_Node_Id
;
961 First_Attribute
: Attribute_Node_Id
;
962 Current_Project
: Project_Node_Id
;
963 Current_Package
: Project_Node_Id
;
964 Packages_To_Check
: String_List_Access
;
965 Is_Config_File
: Boolean;
966 Flags
: Processing_Flags
)
968 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
969 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
970 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
971 Item_Location
: Source_Ptr
:= No_Location
;
974 Declarations
:= Empty_Node
;
977 -- We are always positioned at the token that precedes the first
978 -- token of the declarative element. Scan past it.
982 Item_Location
:= Token_Ptr
;
985 when Tok_Identifier
=>
987 if In_Zone
= In_Case_Construction
then
989 -- Check if the variable has already been declared
992 The_Variable
: Project_Node_Id
:= Empty_Node
;
995 if Present
(Current_Package
) then
997 First_Variable_Of
(Current_Package
, In_Tree
);
998 elsif Present
(Current_Project
) then
1000 First_Variable_Of
(Current_Project
, In_Tree
);
1003 while Present
(The_Variable
)
1004 and then Name_Of
(The_Variable
, In_Tree
) /=
1007 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1010 -- It is an error to declare a variable in a case
1011 -- construction for the first time.
1013 if No
(The_Variable
) then
1016 "a variable cannot be declared " &
1017 "for the first time here",
1023 Parse_Variable_Declaration
1025 Current_Declaration
,
1026 Current_Project
=> Current_Project
,
1027 Current_Package
=> Current_Package
,
1030 Set_End_Of_Line
(Current_Declaration
);
1031 Set_Previous_Line_Node
(Current_Declaration
);
1035 Parse_Attribute_Declaration
1036 (In_Tree
=> In_Tree
,
1037 Attribute
=> Current_Declaration
,
1038 First_Attribute
=> First_Attribute
,
1039 Current_Project
=> Current_Project
,
1040 Current_Package
=> Current_Package
,
1041 Packages_To_Check
=> Packages_To_Check
,
1044 Set_End_Of_Line
(Current_Declaration
);
1045 Set_Previous_Line_Node
(Current_Declaration
);
1049 Scan
(In_Tree
); -- past "null"
1053 -- Package declaration
1055 if In_Zone
/= In_Project
then
1057 (Flags
, "a package cannot be declared here", Token_Ptr
);
1060 Parse_Package_Declaration
1061 (In_Tree
=> In_Tree
,
1062 Package_Declaration
=> Current_Declaration
,
1063 Current_Project
=> Current_Project
,
1064 Packages_To_Check
=> Packages_To_Check
,
1065 Is_Config_File
=> Is_Config_File
,
1068 Set_Previous_End_Node
(Current_Declaration
);
1072 -- Type String Declaration
1074 if In_Zone
/= In_Project
then
1076 "a string type cannot be declared here",
1080 Parse_String_Type_Declaration
1081 (In_Tree
=> In_Tree
,
1082 String_Type
=> Current_Declaration
,
1083 Current_Project
=> Current_Project
,
1086 Set_End_Of_Line
(Current_Declaration
);
1087 Set_Previous_Line_Node
(Current_Declaration
);
1091 -- Case construction
1093 Parse_Case_Construction
1094 (In_Tree
=> In_Tree
,
1095 Case_Construction
=> Current_Declaration
,
1096 First_Attribute
=> First_Attribute
,
1097 Current_Project
=> Current_Project
,
1098 Current_Package
=> Current_Package
,
1099 Packages_To_Check
=> Packages_To_Check
,
1100 Is_Config_File
=> Is_Config_File
,
1103 Set_Previous_End_Node
(Current_Declaration
);
1108 -- We are leaving Parse_Declarative_Items positioned
1109 -- at the first token after the list of declarative items.
1110 -- It could be "end" (for a project, a package declaration or
1111 -- a case construction) or "when" (for a case construction)
1115 Expect
(Tok_Semicolon
, "`;` after declarative items");
1117 -- Insert an N_Declarative_Item in the tree, but only if
1118 -- Current_Declaration is not an empty node.
1120 if Present
(Current_Declaration
) then
1121 if No
(Current_Declarative_Item
) then
1122 Current_Declarative_Item
:=
1123 Default_Project_Node
1124 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1125 Declarations
:= Current_Declarative_Item
;
1128 Next_Declarative_Item
:=
1129 Default_Project_Node
1130 (Of_Kind
=> N_Declarative_Item
, In_Tree
=> In_Tree
);
1131 Set_Next_Declarative_Item
1132 (Current_Declarative_Item
, In_Tree
,
1133 To
=> Next_Declarative_Item
);
1134 Current_Declarative_Item
:= Next_Declarative_Item
;
1137 Set_Current_Item_Node
1138 (Current_Declarative_Item
, In_Tree
,
1139 To
=> Current_Declaration
);
1141 (Current_Declarative_Item
, In_Tree
, To
=> Item_Location
);
1144 end Parse_Declarative_Items
;
1146 -------------------------------
1147 -- Parse_Package_Declaration --
1148 -------------------------------
1150 procedure Parse_Package_Declaration
1151 (In_Tree
: Project_Node_Tree_Ref
;
1152 Package_Declaration
: out Project_Node_Id
;
1153 Current_Project
: Project_Node_Id
;
1154 Packages_To_Check
: String_List_Access
;
1155 Is_Config_File
: Boolean;
1156 Flags
: Processing_Flags
)
1158 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
1159 Current_Package
: Package_Node_Id
:= Empty_Package
;
1160 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
1161 Package_Location
: constant Source_Ptr
:= Token_Ptr
;
1162 Renaming
: Boolean := False;
1163 Extending
: Boolean := False;
1166 Package_Declaration
:=
1167 Default_Project_Node
1168 (Of_Kind
=> N_Package_Declaration
, In_Tree
=> In_Tree
);
1169 Set_Location_Of
(Package_Declaration
, In_Tree
, To
=> Package_Location
);
1171 -- Scan past "package"
1174 Expect
(Tok_Identifier
, "identifier");
1176 if Token
= Tok_Identifier
then
1177 Set_Name_Of
(Package_Declaration
, In_Tree
, To
=> Token_Name
);
1179 Current_Package
:= Package_Node_Id_Of
(Token_Name
);
1181 if Current_Package
= Empty_Package
then
1182 if not Quiet_Output
then
1184 List
: constant Strings
.String_List
:= Package_Name_List
;
1186 Name
: constant String := Get_Name_String
(Token_Name
);
1189 -- Check for possible misspelling of a known package name
1193 if Index
>= List
'Last then
1200 GNAT
.Spelling_Checker
.Is_Bad_Spelling_Of
1201 (Name
, List
(Index
).all);
1204 -- Issue warning(s) in verbose mode or when a possible
1205 -- misspelling has been found.
1207 if Verbose_Mode
or else Index
/= 0 then
1211 (Name_Of
(Package_Declaration
, In_Tree
)) &
1212 """ is not a known package name",
1217 Error_Msg
-- CODEFIX
1219 "\?possible misspelling of """ &
1220 List
(Index
).all & """", Token_Ptr
);
1225 -- Set the package declaration to "ignored" so that it is not
1226 -- processed by Prj.Proc.Process.
1228 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1230 -- Add the unknown package in the list of packages
1232 Add_Unknown_Package
(Token_Name
, Current_Package
);
1234 elsif Current_Package
= Unknown_Package
then
1236 -- Set the package declaration to "ignored" so that it is not
1237 -- processed by Prj.Proc.Process.
1239 Set_Expression_Kind_Of
(Package_Declaration
, In_Tree
, Ignored
);
1242 First_Attribute
:= First_Attribute_Of
(Current_Package
);
1246 (Package_Declaration
, In_Tree
, To
=> Current_Package
);
1249 Current
: Project_Node_Id
:=
1250 First_Package_Of
(Current_Project
, In_Tree
);
1253 while Present
(Current
)
1254 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1256 Current
:= Next_Package_In_Project
(Current
, In_Tree
);
1259 if Present
(Current
) then
1263 Get_Name_String
(Name_Of
(Package_Declaration
, In_Tree
)) &
1264 """ is declared twice in the same project",
1268 -- Add the package to the project list
1270 Set_Next_Package_In_Project
1271 (Package_Declaration
, In_Tree
,
1272 To
=> First_Package_Of
(Current_Project
, In_Tree
));
1273 Set_First_Package_Of
1274 (Current_Project
, In_Tree
, To
=> Package_Declaration
);
1278 -- Scan past the package name
1283 Check_Package_Allowed
1284 (In_Tree
, Current_Project
, Package_Declaration
, Flags
);
1286 if Token
= Tok_Renames
then
1288 elsif Token
= Tok_Extends
then
1292 if Renaming
or else Extending
then
1293 if Is_Config_File
then
1296 "no package rename or extension in configuration projects",
1300 -- Scan past "renames" or "extends"
1304 Expect
(Tok_Identifier
, "identifier");
1306 if Token
= Tok_Identifier
then
1308 Project_Name
: constant Name_Id
:= Token_Name
;
1310 Clause
: Project_Node_Id
:=
1311 First_With_Clause_Of
(Current_Project
, In_Tree
);
1312 The_Project
: Project_Node_Id
:= Empty_Node
;
1313 Extended
: constant Project_Node_Id
:=
1315 (Project_Declaration_Of
1316 (Current_Project
, In_Tree
),
1319 while Present
(Clause
) loop
1320 -- Only non limited imported projects may be used in a
1321 -- renames declaration.
1324 Non_Limited_Project_Node_Of
(Clause
, In_Tree
);
1325 exit when Present
(The_Project
)
1326 and then Name_Of
(The_Project
, In_Tree
) = Project_Name
;
1327 Clause
:= Next_With_Clause_Of
(Clause
, In_Tree
);
1331 -- As we have not found the project in the imports, we check
1332 -- if it's the name of an eventual extended project.
1334 if Present
(Extended
)
1335 and then Name_Of
(Extended
, In_Tree
) = Project_Name
1337 Set_Project_Of_Renamed_Package_Of
1338 (Package_Declaration
, In_Tree
, To
=> Extended
);
1340 Error_Msg_Name_1
:= Project_Name
;
1343 "% is not an imported or extended project", Token_Ptr
);
1346 Set_Project_Of_Renamed_Package_Of
1347 (Package_Declaration
, In_Tree
, To
=> The_Project
);
1352 Expect
(Tok_Dot
, "`.`");
1354 if Token
= Tok_Dot
then
1356 Expect
(Tok_Identifier
, "identifier");
1358 if Token
= Tok_Identifier
then
1359 if Name_Of
(Package_Declaration
, In_Tree
) /= Token_Name
then
1360 Error_Msg
(Flags
, "not the same package name", Token_Ptr
);
1362 Present
(Project_Of_Renamed_Package_Of
1363 (Package_Declaration
, In_Tree
))
1366 Current
: Project_Node_Id
:=
1368 (Project_Of_Renamed_Package_Of
1369 (Package_Declaration
, In_Tree
),
1373 while Present
(Current
)
1374 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1377 Next_Package_In_Project
(Current
, In_Tree
);
1380 if No
(Current
) then
1383 Get_Name_String
(Token_Name
) &
1384 """ is not a package declared by the project",
1397 Expect
(Tok_Semicolon
, "`;`");
1398 Set_End_Of_Line
(Package_Declaration
);
1399 Set_Previous_Line_Node
(Package_Declaration
);
1401 elsif Token
= Tok_Is
then
1402 Set_End_Of_Line
(Package_Declaration
);
1403 Set_Previous_Line_Node
(Package_Declaration
);
1404 Set_Next_End_Node
(Package_Declaration
);
1406 Parse_Declarative_Items
1407 (In_Tree
=> In_Tree
,
1408 Declarations
=> First_Declarative_Item
,
1409 In_Zone
=> In_Package
,
1410 First_Attribute
=> First_Attribute
,
1411 Current_Project
=> Current_Project
,
1412 Current_Package
=> Package_Declaration
,
1413 Packages_To_Check
=> Packages_To_Check
,
1414 Is_Config_File
=> Is_Config_File
,
1417 Set_First_Declarative_Item_Of
1418 (Package_Declaration
, In_Tree
, To
=> First_Declarative_Item
);
1420 Expect
(Tok_End
, "END");
1422 if Token
= Tok_End
then
1429 -- We should have the name of the package after "end"
1431 Expect
(Tok_Identifier
, "identifier");
1433 if Token
= Tok_Identifier
1434 and then Name_Of
(Package_Declaration
, In_Tree
) /= No_Name
1435 and then Token_Name
/= Name_Of
(Package_Declaration
, In_Tree
)
1437 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
, In_Tree
);
1438 Error_Msg
(Flags
, "expected %%", Token_Ptr
);
1441 if Token
/= Tok_Semicolon
then
1443 -- Scan past the package name
1448 Expect
(Tok_Semicolon
, "`;`");
1449 Remove_Next_End_Node
;
1452 Error_Msg
(Flags
, "expected IS", Token_Ptr
);
1455 end Parse_Package_Declaration
;
1457 -----------------------------------
1458 -- Parse_String_Type_Declaration --
1459 -----------------------------------
1461 procedure Parse_String_Type_Declaration
1462 (In_Tree
: Project_Node_Tree_Ref
;
1463 String_Type
: out Project_Node_Id
;
1464 Current_Project
: Project_Node_Id
;
1465 Flags
: Processing_Flags
)
1467 Current
: Project_Node_Id
:= Empty_Node
;
1468 First_String
: Project_Node_Id
:= Empty_Node
;
1472 Default_Project_Node
1473 (Of_Kind
=> N_String_Type_Declaration
, In_Tree
=> In_Tree
);
1475 Set_Location_Of
(String_Type
, In_Tree
, To
=> Token_Ptr
);
1481 Expect
(Tok_Identifier
, "identifier");
1483 if Token
= Tok_Identifier
then
1484 Set_Name_Of
(String_Type
, In_Tree
, To
=> Token_Name
);
1486 Current
:= First_String_Type_Of
(Current_Project
, In_Tree
);
1487 while Present
(Current
)
1489 Name_Of
(Current
, In_Tree
) /= Token_Name
1491 Current
:= Next_String_Type
(Current
, In_Tree
);
1494 if Present
(Current
) then
1496 "duplicate string type name """ &
1497 Get_Name_String
(Token_Name
) &
1501 Current
:= First_Variable_Of
(Current_Project
, In_Tree
);
1502 while Present
(Current
)
1503 and then Name_Of
(Current
, In_Tree
) /= Token_Name
1505 Current
:= Next_Variable
(Current
, In_Tree
);
1508 if Present
(Current
) then
1511 Get_Name_String
(Token_Name
) &
1512 """ is already a variable name", Token_Ptr
);
1514 Set_Next_String_Type
1515 (String_Type
, In_Tree
,
1516 To
=> First_String_Type_Of
(Current_Project
, In_Tree
));
1517 Set_First_String_Type_Of
1518 (Current_Project
, In_Tree
, To
=> String_Type
);
1522 -- Scan past the name
1527 Expect
(Tok_Is
, "IS");
1529 if Token
= Tok_Is
then
1533 Expect
(Tok_Left_Paren
, "`(`");
1535 if Token
= Tok_Left_Paren
then
1539 Parse_String_Type_List
1540 (In_Tree
=> In_Tree
, First_String
=> First_String
, Flags
=> Flags
);
1541 Set_First_Literal_String
(String_Type
, In_Tree
, To
=> First_String
);
1543 Expect
(Tok_Right_Paren
, "`)`");
1545 if Token
= Tok_Right_Paren
then
1549 end Parse_String_Type_Declaration
;
1551 --------------------------------
1552 -- Parse_Variable_Declaration --
1553 --------------------------------
1555 procedure Parse_Variable_Declaration
1556 (In_Tree
: Project_Node_Tree_Ref
;
1557 Variable
: out Project_Node_Id
;
1558 Current_Project
: Project_Node_Id
;
1559 Current_Package
: Project_Node_Id
;
1560 Flags
: Processing_Flags
)
1562 Expression_Location
: Source_Ptr
;
1563 String_Type_Name
: Name_Id
:= No_Name
;
1564 Project_String_Type_Name
: Name_Id
:= No_Name
;
1565 Type_Location
: Source_Ptr
:= No_Location
;
1566 Project_Location
: Source_Ptr
:= No_Location
;
1567 Expression
: Project_Node_Id
:= Empty_Node
;
1568 Variable_Name
: constant Name_Id
:= Token_Name
;
1569 OK
: Boolean := True;
1573 Default_Project_Node
1574 (Of_Kind
=> N_Variable_Declaration
, In_Tree
=> In_Tree
);
1575 Set_Name_Of
(Variable
, In_Tree
, To
=> Variable_Name
);
1576 Set_Location_Of
(Variable
, In_Tree
, To
=> Token_Ptr
);
1578 -- Scan past the variable name
1582 if Token
= Tok_Colon
then
1584 -- Typed string variable declaration
1587 Set_Kind_Of
(Variable
, In_Tree
, N_Typed_Variable_Declaration
);
1588 Expect
(Tok_Identifier
, "identifier");
1590 OK
:= Token
= Tok_Identifier
;
1593 String_Type_Name
:= Token_Name
;
1594 Type_Location
:= Token_Ptr
;
1597 if Token
= Tok_Dot
then
1598 Project_String_Type_Name
:= String_Type_Name
;
1599 Project_Location
:= Type_Location
;
1601 -- Scan past the dot
1604 Expect
(Tok_Identifier
, "identifier");
1606 if Token
= Tok_Identifier
then
1607 String_Type_Name
:= Token_Name
;
1608 Type_Location
:= Token_Ptr
;
1617 Proj
: Project_Node_Id
:= Current_Project
;
1618 Current
: Project_Node_Id
:= Empty_Node
;
1621 if Project_String_Type_Name
/= No_Name
then
1623 The_Project_Name_And_Node
: constant
1624 Tree_Private_Part
.Project_Name_And_Node
:=
1625 Tree_Private_Part
.Projects_Htable
.Get
1626 (In_Tree
.Projects_HT
, Project_String_Type_Name
);
1628 use Tree_Private_Part
;
1631 if The_Project_Name_And_Node
=
1632 Tree_Private_Part
.No_Project_Name_And_Node
1635 "unknown project """ &
1637 (Project_String_Type_Name
) &
1640 Current
:= Empty_Node
;
1643 First_String_Type_Of
1644 (The_Project_Name_And_Node
.Node
, In_Tree
);
1648 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1650 Current
:= Next_String_Type
(Current
, In_Tree
);
1656 -- Look for a string type with the correct name in this
1657 -- project or in any of its ancestors.
1661 First_String_Type_Of
(Proj
, In_Tree
);
1665 Name_Of
(Current
, In_Tree
) /= String_Type_Name
1667 Current
:= Next_String_Type
(Current
, In_Tree
);
1670 exit when Present
(Current
);
1672 Proj
:= Parent_Project_Of
(Proj
, In_Tree
);
1673 exit when No
(Proj
);
1677 if No
(Current
) then
1679 "unknown string type """ &
1680 Get_Name_String
(String_Type_Name
) &
1687 (Variable
, In_Tree
, To
=> Current
);
1694 Expect
(Tok_Colon_Equal
, "`:=`");
1696 OK
:= OK
and then Token
= Tok_Colon_Equal
;
1698 if Token
= Tok_Colon_Equal
then
1702 -- Get the single string or string list value
1704 Expression_Location
:= Token_Ptr
;
1707 (In_Tree
=> In_Tree
,
1708 Expression
=> Expression
,
1710 Current_Project
=> Current_Project
,
1711 Current_Package
=> Current_Package
,
1712 Optional_Index
=> False);
1713 Set_Expression_Of
(Variable
, In_Tree
, To
=> Expression
);
1715 if Present
(Expression
) then
1716 -- A typed string must have a single string value, not a list
1718 if Kind_Of
(Variable
, In_Tree
) = N_Typed_Variable_Declaration
1719 and then Expression_Kind_Of
(Expression
, In_Tree
) = List
1723 "expression must be a single string", Expression_Location
);
1726 Set_Expression_Kind_Of
1728 To
=> Expression_Kind_Of
(Expression
, In_Tree
));
1733 The_Variable
: Project_Node_Id
:= Empty_Node
;
1736 if Present
(Current_Package
) then
1737 The_Variable
:= First_Variable_Of
(Current_Package
, In_Tree
);
1738 elsif Present
(Current_Project
) then
1739 The_Variable
:= First_Variable_Of
(Current_Project
, In_Tree
);
1742 while Present
(The_Variable
)
1743 and then Name_Of
(The_Variable
, In_Tree
) /= Variable_Name
1745 The_Variable
:= Next_Variable
(The_Variable
, In_Tree
);
1748 if No
(The_Variable
) then
1749 if Present
(Current_Package
) then
1752 To
=> First_Variable_Of
(Current_Package
, In_Tree
));
1753 Set_First_Variable_Of
1754 (Current_Package
, In_Tree
, To
=> Variable
);
1756 elsif Present
(Current_Project
) then
1759 To
=> First_Variable_Of
(Current_Project
, In_Tree
));
1760 Set_First_Variable_Of
1761 (Current_Project
, In_Tree
, To
=> Variable
);
1765 if Expression_Kind_Of
(Variable
, In_Tree
) /= Undefined
then
1766 if Expression_Kind_Of
(The_Variable
, In_Tree
) =
1769 Set_Expression_Kind_Of
1770 (The_Variable
, In_Tree
,
1771 To
=> Expression_Kind_Of
(Variable
, In_Tree
));
1774 if Expression_Kind_Of
(The_Variable
, In_Tree
) /=
1775 Expression_Kind_Of
(Variable
, In_Tree
)
1778 "wrong expression kind for variable """ &
1780 (Name_Of
(The_Variable
, In_Tree
)) &
1782 Expression_Location
);
1789 end Parse_Variable_Declaration
;