fixing pr42337
[official-gcc.git] / gcc / ada / prj-dect.adb
blob5795061eacb46d065153ef83e1565ebd4f513ff0
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . D E C T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2009, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
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;
31 with Opt; use Opt;
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;
37 with Snames;
38 with Uintp; use Uintp;
40 with GNAT.Strings;
42 package body Prj.Dect is
44 use GNAT;
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
49 -- (In_Project).
51 procedure Parse_Attribute_Declaration
52 (In_Tree : Project_Node_Tree_Ref;
53 Attribute : out Project_Node_Id;
54 First_Attribute : Attribute_Node_Id;
55 Current_Project : Project_Node_Id;
56 Current_Package : Project_Node_Id;
57 Packages_To_Check : String_List_Access;
58 Flags : Processing_Flags);
59 -- Parse an attribute declaration
61 procedure Parse_Case_Construction
62 (In_Tree : Project_Node_Tree_Ref;
63 Case_Construction : out Project_Node_Id;
64 First_Attribute : Attribute_Node_Id;
65 Current_Project : Project_Node_Id;
66 Current_Package : Project_Node_Id;
67 Packages_To_Check : String_List_Access;
68 Is_Config_File : Boolean;
69 Flags : Processing_Flags);
70 -- Parse a case construction
72 procedure Parse_Declarative_Items
73 (In_Tree : Project_Node_Tree_Ref;
74 Declarations : out Project_Node_Id;
75 In_Zone : Zone;
76 First_Attribute : Attribute_Node_Id;
77 Current_Project : Project_Node_Id;
78 Current_Package : Project_Node_Id;
79 Packages_To_Check : String_List_Access;
80 Is_Config_File : Boolean;
81 Flags : Processing_Flags);
82 -- Parse declarative items. Depending on In_Zone, some declarative items
83 -- may be forbidden. Is_Config_File should be set to True if the project
84 -- represents a config file (.cgpr) since some specific checks apply.
86 procedure Parse_Package_Declaration
87 (In_Tree : Project_Node_Tree_Ref;
88 Package_Declaration : out Project_Node_Id;
89 Current_Project : Project_Node_Id;
90 Packages_To_Check : String_List_Access;
91 Is_Config_File : Boolean;
92 Flags : Processing_Flags);
93 -- Parse a package declaration.
94 -- Is_Config_File should be set to True if the project represents a config
95 -- file (.cgpr) since some specific checks apply.
97 procedure Parse_String_Type_Declaration
98 (In_Tree : Project_Node_Tree_Ref;
99 String_Type : out Project_Node_Id;
100 Current_Project : Project_Node_Id;
101 Flags : Processing_Flags);
102 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
104 procedure Parse_Variable_Declaration
105 (In_Tree : Project_Node_Tree_Ref;
106 Variable : out Project_Node_Id;
107 Current_Project : Project_Node_Id;
108 Current_Package : Project_Node_Id;
109 Flags : Processing_Flags);
110 -- Parse a variable assignment
111 -- <variable_Name> := <expression>; OR
112 -- <variable_Name> : <string_type_Name> := <string_expression>;
114 -----------
115 -- Parse --
116 -----------
118 procedure Parse
119 (In_Tree : Project_Node_Tree_Ref;
120 Declarations : out Project_Node_Id;
121 Current_Project : Project_Node_Id;
122 Extends : Project_Node_Id;
123 Packages_To_Check : String_List_Access;
124 Is_Config_File : Boolean;
125 Flags : Processing_Flags)
127 First_Declarative_Item : Project_Node_Id := Empty_Node;
129 begin
130 Declarations :=
131 Default_Project_Node
132 (Of_Kind => N_Project_Declaration, In_Tree => In_Tree);
133 Set_Location_Of (Declarations, In_Tree, To => Token_Ptr);
134 Set_Extended_Project_Of (Declarations, In_Tree, To => Extends);
135 Set_Project_Declaration_Of (Current_Project, In_Tree, Declarations);
136 Parse_Declarative_Items
137 (Declarations => First_Declarative_Item,
138 In_Tree => In_Tree,
139 In_Zone => In_Project,
140 First_Attribute => Prj.Attr.Attribute_First,
141 Current_Project => Current_Project,
142 Current_Package => Empty_Node,
143 Packages_To_Check => Packages_To_Check,
144 Is_Config_File => Is_Config_File,
145 Flags => Flags);
146 Set_First_Declarative_Item_Of
147 (Declarations, In_Tree, To => First_Declarative_Item);
148 end Parse;
150 ---------------------------------
151 -- Parse_Attribute_Declaration --
152 ---------------------------------
154 procedure Parse_Attribute_Declaration
155 (In_Tree : Project_Node_Tree_Ref;
156 Attribute : out Project_Node_Id;
157 First_Attribute : Attribute_Node_Id;
158 Current_Project : Project_Node_Id;
159 Current_Package : Project_Node_Id;
160 Packages_To_Check : String_List_Access;
161 Flags : Processing_Flags)
163 Current_Attribute : Attribute_Node_Id := First_Attribute;
164 Full_Associative_Array : Boolean := False;
165 Attribute_Name : Name_Id := No_Name;
166 Optional_Index : Boolean := False;
167 Pkg_Id : Package_Node_Id := Empty_Package;
168 Ignore : Boolean := False;
170 begin
171 Attribute :=
172 Default_Project_Node
173 (Of_Kind => N_Attribute_Declaration, In_Tree => In_Tree);
174 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
175 Set_Previous_Line_Node (Attribute);
177 -- Scan past "for"
179 Scan (In_Tree);
181 -- Body may be an attribute name
183 if Token = Tok_Body then
184 Token := Tok_Identifier;
185 Token_Name := Snames.Name_Body;
186 end if;
188 Expect (Tok_Identifier, "identifier");
190 if Token = Tok_Identifier then
191 Attribute_Name := Token_Name;
192 Set_Name_Of (Attribute, In_Tree, To => Token_Name);
193 Set_Location_Of (Attribute, In_Tree, To => Token_Ptr);
195 -- Find the attribute
197 Current_Attribute :=
198 Attribute_Node_Id_Of (Token_Name, First_Attribute);
200 -- If the attribute cannot be found, create the attribute if inside
201 -- an unknown package.
203 if Current_Attribute = Empty_Attribute then
204 if Present (Current_Package)
205 and then Expression_Kind_Of (Current_Package, In_Tree) = Ignored
206 then
207 Pkg_Id := Package_Id_Of (Current_Package, In_Tree);
208 Add_Attribute (Pkg_Id, Token_Name, Current_Attribute);
210 else
211 -- If not a valid attribute name, issue an error if inside
212 -- a package that need to be checked.
214 Ignore := Present (Current_Package) and then
215 Packages_To_Check /= All_Packages;
217 if Ignore then
219 -- Check that we are not in a package to check
221 Get_Name_String (Name_Of (Current_Package, In_Tree));
223 for Index in Packages_To_Check'Range loop
224 if Name_Buffer (1 .. Name_Len) =
225 Packages_To_Check (Index).all
226 then
227 Ignore := False;
228 exit;
229 end if;
230 end loop;
231 end if;
233 if not Ignore then
234 Error_Msg_Name_1 := Token_Name;
235 Error_Msg (Flags, "undefined attribute %%", Token_Ptr);
236 end if;
237 end if;
239 -- Set, if appropriate the index case insensitivity flag
241 else
242 if Is_Read_Only (Current_Attribute) then
243 Error_Msg_Name_1 := Token_Name;
244 Error_Msg
245 (Flags, "read-only attribute %% cannot be given a value",
246 Token_Ptr);
247 end if;
249 if Attribute_Kind_Of (Current_Attribute) in
250 Case_Insensitive_Associative_Array ..
251 Optional_Index_Case_Insensitive_Associative_Array
252 then
253 Set_Case_Insensitive (Attribute, In_Tree, To => True);
254 end if;
255 end if;
257 Scan (In_Tree); -- past the attribute name
258 end if;
260 -- Change obsolete names of attributes to the new names
262 if Present (Current_Package)
263 and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored
264 then
265 case Name_Of (Attribute, In_Tree) is
266 when Snames.Name_Specification =>
267 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec);
269 when Snames.Name_Specification_Suffix =>
270 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix);
272 when Snames.Name_Implementation =>
273 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body);
275 when Snames.Name_Implementation_Suffix =>
276 Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix);
278 when others =>
279 null;
280 end case;
281 end if;
283 -- Associative array attributes
285 if Token = Tok_Left_Paren then
287 -- If the attribute is not an associative array attribute, report
288 -- an error. If this information is still unknown, set the kind
289 -- to Associative_Array.
291 if Current_Attribute /= Empty_Attribute
292 and then Attribute_Kind_Of (Current_Attribute) = Single
293 then
294 Error_Msg (Flags,
295 "the attribute """ &
296 Get_Name_String
297 (Attribute_Name_Of (Current_Attribute)) &
298 """ cannot be an associative array",
299 Location_Of (Attribute, In_Tree));
301 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
302 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
303 end if;
305 Scan (In_Tree); -- past the left parenthesis
307 if Others_Allowed_For (Current_Attribute)
308 and then Token = Tok_Others
309 then
310 Set_Associative_Array_Index_Of
311 (Attribute, In_Tree, All_Other_Names);
312 Scan (In_Tree); -- past others
314 else
315 if Others_Allowed_For (Current_Attribute) then
316 Expect (Tok_String_Literal, "literal string or others");
317 else
318 Expect (Tok_String_Literal, "literal string");
319 end if;
321 if Token = Tok_String_Literal then
322 Get_Name_String (Token_Name);
324 if Case_Insensitive (Attribute, In_Tree) then
325 To_Lower (Name_Buffer (1 .. Name_Len));
326 end if;
328 Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find);
329 Scan (In_Tree); -- past the literal string index
331 if Token = Tok_At then
332 case Attribute_Kind_Of (Current_Attribute) is
333 when Optional_Index_Associative_Array |
334 Optional_Index_Case_Insensitive_Associative_Array =>
335 Scan (In_Tree);
336 Expect (Tok_Integer_Literal, "integer literal");
338 if Token = Tok_Integer_Literal then
340 -- Set the source index value from given literal
342 declare
343 Index : constant Int :=
344 UI_To_Int (Int_Literal_Value);
345 begin
346 if Index = 0 then
347 Error_Msg
348 (Flags, "index cannot be zero", Token_Ptr);
349 else
350 Set_Source_Index_Of
351 (Attribute, In_Tree, To => Index);
352 end if;
353 end;
355 Scan (In_Tree);
356 end if;
358 when others =>
359 Error_Msg (Flags, "index not allowed here", Token_Ptr);
360 Scan (In_Tree);
362 if Token = Tok_Integer_Literal then
363 Scan (In_Tree);
364 end if;
365 end case;
366 end if;
367 end if;
368 end if;
370 Expect (Tok_Right_Paren, "`)`");
372 if Token = Tok_Right_Paren then
373 Scan (In_Tree); -- past the right parenthesis
374 end if;
376 else
377 -- If it is an associative array attribute and there are no left
378 -- parenthesis, then this is a full associative array declaration.
379 -- Flag it as such for later processing of its value.
381 if Current_Attribute /= Empty_Attribute
382 and then
383 Attribute_Kind_Of (Current_Attribute) /= Single
384 then
385 if Attribute_Kind_Of (Current_Attribute) = Unknown then
386 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
388 else
389 Full_Associative_Array := True;
390 end if;
391 end if;
392 end if;
394 -- Set the expression kind of the attribute
396 if Current_Attribute /= Empty_Attribute then
397 Set_Expression_Kind_Of
398 (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute));
399 Optional_Index := Optional_Index_Of (Current_Attribute);
400 end if;
402 Expect (Tok_Use, "USE");
404 if Token = Tok_Use then
405 Scan (In_Tree);
407 if Full_Associative_Array then
409 -- Expect <project>'<same_attribute_name>, or
410 -- <project>.<same_package_name>'<same_attribute_name>
412 declare
413 The_Project : Project_Node_Id := Empty_Node;
414 -- The node of the project where the associative array is
415 -- declared.
417 The_Package : Project_Node_Id := Empty_Node;
418 -- The node of the package where the associative array is
419 -- declared, if any.
421 Project_Name : Name_Id := No_Name;
422 -- The name of the project where the associative array is
423 -- declared.
425 Location : Source_Ptr := No_Location;
426 -- The location of the project name
428 begin
429 Expect (Tok_Identifier, "identifier");
431 if Token = Tok_Identifier then
432 Location := Token_Ptr;
434 -- Find the project node in the imported project or
435 -- in the project being extended.
437 The_Project := Imported_Or_Extended_Project_Of
438 (Current_Project, In_Tree, Token_Name);
440 if No (The_Project) then
441 Error_Msg (Flags, "unknown project", Location);
442 Scan (In_Tree); -- past the project name
444 else
445 Project_Name := Token_Name;
446 Scan (In_Tree); -- past the project name
448 -- If this is inside a package, a dot followed by the
449 -- name of the package must followed the project name.
451 if Present (Current_Package) then
452 Expect (Tok_Dot, "`.`");
454 if Token /= Tok_Dot then
455 The_Project := Empty_Node;
457 else
458 Scan (In_Tree); -- past the dot
459 Expect (Tok_Identifier, "identifier");
461 if Token /= Tok_Identifier then
462 The_Project := Empty_Node;
464 -- If it is not the same package name, issue error
466 elsif
467 Token_Name /= Name_Of (Current_Package, In_Tree)
468 then
469 The_Project := Empty_Node;
470 Error_Msg
471 (Flags, "not the same package as " &
472 Get_Name_String
473 (Name_Of (Current_Package, In_Tree)),
474 Token_Ptr);
476 else
477 The_Package :=
478 First_Package_Of (The_Project, In_Tree);
480 -- Look for the package node
482 while Present (The_Package)
483 and then
484 Name_Of (The_Package, In_Tree) /= Token_Name
485 loop
486 The_Package :=
487 Next_Package_In_Project
488 (The_Package, In_Tree);
489 end loop;
491 -- If the package cannot be found in the
492 -- project, issue an error.
494 if No (The_Package) then
495 The_Project := Empty_Node;
496 Error_Msg_Name_2 := Project_Name;
497 Error_Msg_Name_1 := Token_Name;
498 Error_Msg
499 (Flags,
500 "package % not declared in project %",
501 Token_Ptr);
502 end if;
504 Scan (In_Tree); -- past the package name
505 end if;
506 end if;
507 end if;
508 end if;
509 end if;
511 if Present (The_Project) then
513 -- Looking for '<same attribute name>
515 Expect (Tok_Apostrophe, "`''`");
517 if Token /= Tok_Apostrophe then
518 The_Project := Empty_Node;
520 else
521 Scan (In_Tree); -- past the apostrophe
522 Expect (Tok_Identifier, "identifier");
524 if Token /= Tok_Identifier then
525 The_Project := Empty_Node;
527 else
528 -- If it is not the same attribute name, issue error
530 if Token_Name /= Attribute_Name then
531 The_Project := Empty_Node;
532 Error_Msg_Name_1 := Attribute_Name;
533 Error_Msg
534 (Flags, "invalid name, should be %", Token_Ptr);
535 end if;
537 Scan (In_Tree); -- past the attribute name
538 end if;
539 end if;
540 end if;
542 if No (The_Project) then
544 -- If there were any problem, set the attribute id to null,
545 -- so that the node will not be recorded.
547 Current_Attribute := Empty_Attribute;
549 else
550 -- Set the appropriate field in the node.
551 -- Note that the index and the expression are nil. This
552 -- characterizes full associative array attribute
553 -- declarations.
555 Set_Associative_Project_Of (Attribute, In_Tree, The_Project);
556 Set_Associative_Package_Of (Attribute, In_Tree, The_Package);
557 end if;
558 end;
560 -- Other attribute declarations (not full associative array)
562 else
563 declare
564 Expression_Location : constant Source_Ptr := Token_Ptr;
565 -- The location of the first token of the expression
567 Expression : Project_Node_Id := Empty_Node;
568 -- The expression, value for the attribute declaration
570 begin
571 -- Get the expression value and set it in the attribute node
573 Parse_Expression
574 (In_Tree => In_Tree,
575 Expression => Expression,
576 Flags => Flags,
577 Current_Project => Current_Project,
578 Current_Package => Current_Package,
579 Optional_Index => Optional_Index);
580 Set_Expression_Of (Attribute, In_Tree, To => Expression);
582 -- If the expression is legal, but not of the right kind
583 -- for the attribute, issue an error.
585 if Current_Attribute /= Empty_Attribute
586 and then Present (Expression)
587 and then Variable_Kind_Of (Current_Attribute) /=
588 Expression_Kind_Of (Expression, In_Tree)
589 then
590 if Variable_Kind_Of (Current_Attribute) = Undefined then
591 Set_Variable_Kind_Of
592 (Current_Attribute,
593 To => Expression_Kind_Of (Expression, In_Tree));
595 else
596 Error_Msg
597 (Flags, "wrong expression kind for attribute """ &
598 Get_Name_String
599 (Attribute_Name_Of (Current_Attribute)) &
600 """",
601 Expression_Location);
602 end if;
603 end if;
604 end;
605 end if;
606 end if;
608 -- If the attribute was not recognized, return an empty node.
609 -- It may be that it is not in a package to check, and the node will
610 -- not be added to the tree.
612 if Current_Attribute = Empty_Attribute then
613 Attribute := Empty_Node;
614 end if;
616 Set_End_Of_Line (Attribute);
617 Set_Previous_Line_Node (Attribute);
618 end Parse_Attribute_Declaration;
620 -----------------------------
621 -- Parse_Case_Construction --
622 -----------------------------
624 procedure Parse_Case_Construction
625 (In_Tree : Project_Node_Tree_Ref;
626 Case_Construction : out Project_Node_Id;
627 First_Attribute : Attribute_Node_Id;
628 Current_Project : Project_Node_Id;
629 Current_Package : Project_Node_Id;
630 Packages_To_Check : String_List_Access;
631 Is_Config_File : Boolean;
632 Flags : Processing_Flags)
634 Current_Item : Project_Node_Id := Empty_Node;
635 Next_Item : Project_Node_Id := Empty_Node;
636 First_Case_Item : Boolean := True;
638 Variable_Location : Source_Ptr := No_Location;
640 String_Type : Project_Node_Id := Empty_Node;
642 Case_Variable : Project_Node_Id := Empty_Node;
644 First_Declarative_Item : Project_Node_Id := Empty_Node;
646 First_Choice : Project_Node_Id := Empty_Node;
648 When_Others : Boolean := False;
649 -- Set to True when there is a "when others =>" clause
651 begin
652 Case_Construction :=
653 Default_Project_Node
654 (Of_Kind => N_Case_Construction, In_Tree => In_Tree);
655 Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr);
657 -- Scan past "case"
659 Scan (In_Tree);
661 -- Get the switch variable
663 Expect (Tok_Identifier, "identifier");
665 if Token = Tok_Identifier then
666 Variable_Location := Token_Ptr;
667 Parse_Variable_Reference
668 (In_Tree => In_Tree,
669 Variable => Case_Variable,
670 Flags => Flags,
671 Current_Project => Current_Project,
672 Current_Package => Current_Package);
673 Set_Case_Variable_Reference_Of
674 (Case_Construction, In_Tree, To => Case_Variable);
676 else
677 if Token /= Tok_Is then
678 Scan (In_Tree);
679 end if;
680 end if;
682 if Present (Case_Variable) then
683 String_Type := String_Type_Of (Case_Variable, In_Tree);
685 if No (String_Type) then
686 Error_Msg (Flags,
687 "variable """ &
688 Get_Name_String (Name_Of (Case_Variable, In_Tree)) &
689 """ is not typed",
690 Variable_Location);
691 end if;
692 end if;
694 Expect (Tok_Is, "IS");
696 if Token = Tok_Is then
697 Set_End_Of_Line (Case_Construction);
698 Set_Previous_Line_Node (Case_Construction);
699 Set_Next_End_Node (Case_Construction);
701 -- Scan past "is"
703 Scan (In_Tree);
704 end if;
706 Start_New_Case_Construction (In_Tree, String_Type);
708 When_Loop :
710 while Token = Tok_When loop
712 if First_Case_Item then
713 Current_Item :=
714 Default_Project_Node
715 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
716 Set_First_Case_Item_Of
717 (Case_Construction, In_Tree, To => Current_Item);
718 First_Case_Item := False;
720 else
721 Next_Item :=
722 Default_Project_Node
723 (Of_Kind => N_Case_Item, In_Tree => In_Tree);
724 Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item);
725 Current_Item := Next_Item;
726 end if;
728 Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr);
730 -- Scan past "when"
732 Scan (In_Tree);
734 if Token = Tok_Others then
735 When_Others := True;
737 -- Scan past "others"
739 Scan (In_Tree);
741 Expect (Tok_Arrow, "`=>`");
742 Set_End_Of_Line (Current_Item);
743 Set_Previous_Line_Node (Current_Item);
745 -- Empty_Node in Field1 of a Case_Item indicates
746 -- the "when others =>" branch.
748 Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node);
750 Parse_Declarative_Items
751 (In_Tree => In_Tree,
752 Declarations => First_Declarative_Item,
753 In_Zone => In_Case_Construction,
754 First_Attribute => First_Attribute,
755 Current_Project => Current_Project,
756 Current_Package => Current_Package,
757 Packages_To_Check => Packages_To_Check,
758 Is_Config_File => Is_Config_File,
759 Flags => Flags);
761 -- "when others =>" must be the last branch, so save the
762 -- Case_Item and exit
764 Set_First_Declarative_Item_Of
765 (Current_Item, In_Tree, To => First_Declarative_Item);
766 exit When_Loop;
768 else
769 Parse_Choice_List
770 (In_Tree => In_Tree,
771 First_Choice => First_Choice,
772 Flags => Flags);
773 Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice);
775 Expect (Tok_Arrow, "`=>`");
776 Set_End_Of_Line (Current_Item);
777 Set_Previous_Line_Node (Current_Item);
779 Parse_Declarative_Items
780 (In_Tree => In_Tree,
781 Declarations => First_Declarative_Item,
782 In_Zone => In_Case_Construction,
783 First_Attribute => First_Attribute,
784 Current_Project => Current_Project,
785 Current_Package => Current_Package,
786 Packages_To_Check => Packages_To_Check,
787 Is_Config_File => Is_Config_File,
788 Flags => Flags);
790 Set_First_Declarative_Item_Of
791 (Current_Item, In_Tree, To => First_Declarative_Item);
793 end if;
794 end loop When_Loop;
796 End_Case_Construction
797 (Check_All_Labels => not When_Others and not Quiet_Output,
798 Case_Location => Location_Of (Case_Construction, In_Tree),
799 Flags => Flags);
801 Expect (Tok_End, "`END CASE`");
802 Remove_Next_End_Node;
804 if Token = Tok_End then
806 -- Scan past "end"
808 Scan (In_Tree);
810 Expect (Tok_Case, "CASE");
812 end if;
814 -- Scan past "case"
816 Scan (In_Tree);
818 Expect (Tok_Semicolon, "`;`");
819 Set_Previous_End_Node (Case_Construction);
821 end Parse_Case_Construction;
823 -----------------------------
824 -- Parse_Declarative_Items --
825 -----------------------------
827 procedure Parse_Declarative_Items
828 (In_Tree : Project_Node_Tree_Ref;
829 Declarations : out Project_Node_Id;
830 In_Zone : Zone;
831 First_Attribute : Attribute_Node_Id;
832 Current_Project : Project_Node_Id;
833 Current_Package : Project_Node_Id;
834 Packages_To_Check : String_List_Access;
835 Is_Config_File : Boolean;
836 Flags : Processing_Flags)
838 Current_Declarative_Item : Project_Node_Id := Empty_Node;
839 Next_Declarative_Item : Project_Node_Id := Empty_Node;
840 Current_Declaration : Project_Node_Id := Empty_Node;
841 Item_Location : Source_Ptr := No_Location;
843 begin
844 Declarations := Empty_Node;
846 loop
847 -- We are always positioned at the token that precedes the first
848 -- token of the declarative element. Scan past it.
850 Scan (In_Tree);
852 Item_Location := Token_Ptr;
854 case Token is
855 when Tok_Identifier =>
857 if In_Zone = In_Case_Construction then
859 -- Check if the variable has already been declared
861 declare
862 The_Variable : Project_Node_Id := Empty_Node;
864 begin
865 if Present (Current_Package) then
866 The_Variable :=
867 First_Variable_Of (Current_Package, In_Tree);
868 elsif Present (Current_Project) then
869 The_Variable :=
870 First_Variable_Of (Current_Project, In_Tree);
871 end if;
873 while Present (The_Variable)
874 and then Name_Of (The_Variable, In_Tree) /=
875 Token_Name
876 loop
877 The_Variable := Next_Variable (The_Variable, In_Tree);
878 end loop;
880 -- It is an error to declare a variable in a case
881 -- construction for the first time.
883 if No (The_Variable) then
884 Error_Msg
885 (Flags,
886 "a variable cannot be declared " &
887 "for the first time here",
888 Token_Ptr);
889 end if;
890 end;
891 end if;
893 Parse_Variable_Declaration
894 (In_Tree,
895 Current_Declaration,
896 Current_Project => Current_Project,
897 Current_Package => Current_Package,
898 Flags => Flags);
900 Set_End_Of_Line (Current_Declaration);
901 Set_Previous_Line_Node (Current_Declaration);
903 when Tok_For =>
905 Parse_Attribute_Declaration
906 (In_Tree => In_Tree,
907 Attribute => Current_Declaration,
908 First_Attribute => First_Attribute,
909 Current_Project => Current_Project,
910 Current_Package => Current_Package,
911 Packages_To_Check => Packages_To_Check,
912 Flags => Flags);
914 Set_End_Of_Line (Current_Declaration);
915 Set_Previous_Line_Node (Current_Declaration);
917 when Tok_Null =>
919 Scan (In_Tree); -- past "null"
921 when Tok_Package =>
923 -- Package declaration
925 if In_Zone /= In_Project then
926 Error_Msg
927 (Flags, "a package cannot be declared here", Token_Ptr);
928 end if;
930 Parse_Package_Declaration
931 (In_Tree => In_Tree,
932 Package_Declaration => Current_Declaration,
933 Current_Project => Current_Project,
934 Packages_To_Check => Packages_To_Check,
935 Is_Config_File => Is_Config_File,
936 Flags => Flags);
938 Set_Previous_End_Node (Current_Declaration);
940 when Tok_Type =>
942 -- Type String Declaration
944 if In_Zone /= In_Project then
945 Error_Msg (Flags,
946 "a string type cannot be declared here",
947 Token_Ptr);
948 end if;
950 Parse_String_Type_Declaration
951 (In_Tree => In_Tree,
952 String_Type => Current_Declaration,
953 Current_Project => Current_Project,
954 Flags => Flags);
956 Set_End_Of_Line (Current_Declaration);
957 Set_Previous_Line_Node (Current_Declaration);
959 when Tok_Case =>
961 -- Case construction
963 Parse_Case_Construction
964 (In_Tree => In_Tree,
965 Case_Construction => Current_Declaration,
966 First_Attribute => First_Attribute,
967 Current_Project => Current_Project,
968 Current_Package => Current_Package,
969 Packages_To_Check => Packages_To_Check,
970 Is_Config_File => Is_Config_File,
971 Flags => Flags);
973 Set_Previous_End_Node (Current_Declaration);
975 when others =>
976 exit;
978 -- We are leaving Parse_Declarative_Items positioned
979 -- at the first token after the list of declarative items.
980 -- It could be "end" (for a project, a package declaration or
981 -- a case construction) or "when" (for a case construction)
983 end case;
985 Expect (Tok_Semicolon, "`;` after declarative items");
987 -- Insert an N_Declarative_Item in the tree, but only if
988 -- Current_Declaration is not an empty node.
990 if Present (Current_Declaration) then
991 if No (Current_Declarative_Item) then
992 Current_Declarative_Item :=
993 Default_Project_Node
994 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
995 Declarations := Current_Declarative_Item;
997 else
998 Next_Declarative_Item :=
999 Default_Project_Node
1000 (Of_Kind => N_Declarative_Item, In_Tree => In_Tree);
1001 Set_Next_Declarative_Item
1002 (Current_Declarative_Item, In_Tree,
1003 To => Next_Declarative_Item);
1004 Current_Declarative_Item := Next_Declarative_Item;
1005 end if;
1007 Set_Current_Item_Node
1008 (Current_Declarative_Item, In_Tree,
1009 To => Current_Declaration);
1010 Set_Location_Of
1011 (Current_Declarative_Item, In_Tree, To => Item_Location);
1012 end if;
1013 end loop;
1014 end Parse_Declarative_Items;
1016 -------------------------------
1017 -- Parse_Package_Declaration --
1018 -------------------------------
1020 procedure Parse_Package_Declaration
1021 (In_Tree : Project_Node_Tree_Ref;
1022 Package_Declaration : out Project_Node_Id;
1023 Current_Project : Project_Node_Id;
1024 Packages_To_Check : String_List_Access;
1025 Is_Config_File : Boolean;
1026 Flags : Processing_Flags)
1028 First_Attribute : Attribute_Node_Id := Empty_Attribute;
1029 Current_Package : Package_Node_Id := Empty_Package;
1030 First_Declarative_Item : Project_Node_Id := Empty_Node;
1032 Package_Location : constant Source_Ptr := Token_Ptr;
1034 begin
1035 Package_Declaration :=
1036 Default_Project_Node
1037 (Of_Kind => N_Package_Declaration, In_Tree => In_Tree);
1038 Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location);
1040 -- Scan past "package"
1042 Scan (In_Tree);
1043 Expect (Tok_Identifier, "identifier");
1045 if Token = Tok_Identifier then
1046 Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name);
1048 Current_Package := Package_Node_Id_Of (Token_Name);
1050 if Current_Package = Empty_Package then
1051 if not Quiet_Output then
1052 declare
1053 List : constant Strings.String_List := Package_Name_List;
1054 Index : Natural;
1055 Name : constant String := Get_Name_String (Token_Name);
1057 begin
1058 -- Check for possible misspelling of a known package name
1060 Index := 0;
1061 loop
1062 if Index >= List'Last then
1063 Index := 0;
1064 exit;
1065 end if;
1067 Index := Index + 1;
1068 exit when
1069 GNAT.Spelling_Checker.Is_Bad_Spelling_Of
1070 (Name, List (Index).all);
1071 end loop;
1073 -- Issue warning(s) in verbose mode or when a possible
1074 -- misspelling has been found.
1076 if Verbose_Mode or else Index /= 0 then
1077 Error_Msg (Flags,
1078 "?""" &
1079 Get_Name_String
1080 (Name_Of (Package_Declaration, In_Tree)) &
1081 """ is not a known package name",
1082 Token_Ptr);
1083 end if;
1085 if Index /= 0 then
1086 Error_Msg -- CODEFIX
1087 (Flags,
1088 "\?possible misspelling of """ &
1089 List (Index).all & """", Token_Ptr);
1090 end if;
1091 end;
1092 end if;
1094 -- Set the package declaration to "ignored" so that it is not
1095 -- processed by Prj.Proc.Process.
1097 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1099 -- Add the unknown package in the list of packages
1101 Add_Unknown_Package (Token_Name, Current_Package);
1103 elsif Current_Package = Unknown_Package then
1105 -- Set the package declaration to "ignored" so that it is not
1106 -- processed by Prj.Proc.Process.
1108 Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored);
1110 else
1111 First_Attribute := First_Attribute_Of (Current_Package);
1112 end if;
1114 Set_Package_Id_Of
1115 (Package_Declaration, In_Tree, To => Current_Package);
1117 declare
1118 Current : Project_Node_Id :=
1119 First_Package_Of (Current_Project, In_Tree);
1121 begin
1122 while Present (Current)
1123 and then Name_Of (Current, In_Tree) /= Token_Name
1124 loop
1125 Current := Next_Package_In_Project (Current, In_Tree);
1126 end loop;
1128 if Present (Current) then
1129 Error_Msg
1130 (Flags,
1131 "package """ &
1132 Get_Name_String (Name_Of (Package_Declaration, In_Tree)) &
1133 """ is declared twice in the same project",
1134 Token_Ptr);
1136 else
1137 -- Add the package to the project list
1139 Set_Next_Package_In_Project
1140 (Package_Declaration, In_Tree,
1141 To => First_Package_Of (Current_Project, In_Tree));
1142 Set_First_Package_Of
1143 (Current_Project, In_Tree, To => Package_Declaration);
1144 end if;
1145 end;
1147 -- Scan past the package name
1149 Scan (In_Tree);
1150 end if;
1152 if Token = Tok_Renames then
1153 if Is_Config_File then
1154 Error_Msg
1155 (Flags,
1156 "no package renames in configuration projects", Token_Ptr);
1157 end if;
1159 -- Scan past "renames"
1161 Scan (In_Tree);
1163 Expect (Tok_Identifier, "identifier");
1165 if Token = Tok_Identifier then
1166 declare
1167 Project_Name : constant Name_Id := Token_Name;
1169 Clause : Project_Node_Id :=
1170 First_With_Clause_Of (Current_Project, In_Tree);
1171 The_Project : Project_Node_Id := Empty_Node;
1172 Extended : constant Project_Node_Id :=
1173 Extended_Project_Of
1174 (Project_Declaration_Of
1175 (Current_Project, In_Tree),
1176 In_Tree);
1177 begin
1178 while Present (Clause) loop
1179 -- Only non limited imported projects may be used in a
1180 -- renames declaration.
1182 The_Project :=
1183 Non_Limited_Project_Node_Of (Clause, In_Tree);
1184 exit when Present (The_Project)
1185 and then Name_Of (The_Project, In_Tree) = Project_Name;
1186 Clause := Next_With_Clause_Of (Clause, In_Tree);
1187 end loop;
1189 if No (Clause) then
1190 -- As we have not found the project in the imports, we check
1191 -- if it's the name of an eventual extended project.
1193 if Present (Extended)
1194 and then Name_Of (Extended, In_Tree) = Project_Name
1195 then
1196 Set_Project_Of_Renamed_Package_Of
1197 (Package_Declaration, In_Tree, To => Extended);
1198 else
1199 Error_Msg_Name_1 := Project_Name;
1200 Error_Msg
1201 (Flags,
1202 "% is not an imported or extended project", Token_Ptr);
1203 end if;
1204 else
1205 Set_Project_Of_Renamed_Package_Of
1206 (Package_Declaration, In_Tree, To => The_Project);
1207 end if;
1208 end;
1210 Scan (In_Tree);
1211 Expect (Tok_Dot, "`.`");
1213 if Token = Tok_Dot then
1214 Scan (In_Tree);
1215 Expect (Tok_Identifier, "identifier");
1217 if Token = Tok_Identifier then
1218 if Name_Of (Package_Declaration, In_Tree) /= Token_Name then
1219 Error_Msg (Flags, "not the same package name", Token_Ptr);
1220 elsif
1221 Present (Project_Of_Renamed_Package_Of
1222 (Package_Declaration, In_Tree))
1223 then
1224 declare
1225 Current : Project_Node_Id :=
1226 First_Package_Of
1227 (Project_Of_Renamed_Package_Of
1228 (Package_Declaration, In_Tree),
1229 In_Tree);
1231 begin
1232 while Present (Current)
1233 and then Name_Of (Current, In_Tree) /= Token_Name
1234 loop
1235 Current :=
1236 Next_Package_In_Project (Current, In_Tree);
1237 end loop;
1239 if No (Current) then
1240 Error_Msg
1241 (Flags, """" &
1242 Get_Name_String (Token_Name) &
1243 """ is not a package declared by the project",
1244 Token_Ptr);
1245 end if;
1246 end;
1247 end if;
1249 Scan (In_Tree);
1250 end if;
1251 end if;
1252 end if;
1254 Expect (Tok_Semicolon, "`;`");
1255 Set_End_Of_Line (Package_Declaration);
1256 Set_Previous_Line_Node (Package_Declaration);
1258 elsif Token = Tok_Is then
1259 Set_End_Of_Line (Package_Declaration);
1260 Set_Previous_Line_Node (Package_Declaration);
1261 Set_Next_End_Node (Package_Declaration);
1263 Parse_Declarative_Items
1264 (In_Tree => In_Tree,
1265 Declarations => First_Declarative_Item,
1266 In_Zone => In_Package,
1267 First_Attribute => First_Attribute,
1268 Current_Project => Current_Project,
1269 Current_Package => Package_Declaration,
1270 Packages_To_Check => Packages_To_Check,
1271 Is_Config_File => Is_Config_File,
1272 Flags => Flags);
1274 Set_First_Declarative_Item_Of
1275 (Package_Declaration, In_Tree, To => First_Declarative_Item);
1277 Expect (Tok_End, "END");
1279 if Token = Tok_End then
1281 -- Scan past "end"
1283 Scan (In_Tree);
1284 end if;
1286 -- We should have the name of the package after "end"
1288 Expect (Tok_Identifier, "identifier");
1290 if Token = Tok_Identifier
1291 and then Name_Of (Package_Declaration, In_Tree) /= No_Name
1292 and then Token_Name /= Name_Of (Package_Declaration, In_Tree)
1293 then
1294 Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree);
1295 Error_Msg (Flags, "expected %%", Token_Ptr);
1296 end if;
1298 if Token /= Tok_Semicolon then
1300 -- Scan past the package name
1302 Scan (In_Tree);
1303 end if;
1305 Expect (Tok_Semicolon, "`;`");
1306 Remove_Next_End_Node;
1308 else
1309 Error_Msg (Flags, "expected IS or RENAMES", Token_Ptr);
1310 end if;
1312 end Parse_Package_Declaration;
1314 -----------------------------------
1315 -- Parse_String_Type_Declaration --
1316 -----------------------------------
1318 procedure Parse_String_Type_Declaration
1319 (In_Tree : Project_Node_Tree_Ref;
1320 String_Type : out Project_Node_Id;
1321 Current_Project : Project_Node_Id;
1322 Flags : Processing_Flags)
1324 Current : Project_Node_Id := Empty_Node;
1325 First_String : Project_Node_Id := Empty_Node;
1327 begin
1328 String_Type :=
1329 Default_Project_Node
1330 (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree);
1332 Set_Location_Of (String_Type, In_Tree, To => Token_Ptr);
1334 -- Scan past "type"
1336 Scan (In_Tree);
1338 Expect (Tok_Identifier, "identifier");
1340 if Token = Tok_Identifier then
1341 Set_Name_Of (String_Type, In_Tree, To => Token_Name);
1343 Current := First_String_Type_Of (Current_Project, In_Tree);
1344 while Present (Current)
1345 and then
1346 Name_Of (Current, In_Tree) /= Token_Name
1347 loop
1348 Current := Next_String_Type (Current, In_Tree);
1349 end loop;
1351 if Present (Current) then
1352 Error_Msg (Flags,
1353 "duplicate string type name """ &
1354 Get_Name_String (Token_Name) &
1355 """",
1356 Token_Ptr);
1357 else
1358 Current := First_Variable_Of (Current_Project, In_Tree);
1359 while Present (Current)
1360 and then Name_Of (Current, In_Tree) /= Token_Name
1361 loop
1362 Current := Next_Variable (Current, In_Tree);
1363 end loop;
1365 if Present (Current) then
1366 Error_Msg (Flags,
1367 """" &
1368 Get_Name_String (Token_Name) &
1369 """ is already a variable name", Token_Ptr);
1370 else
1371 Set_Next_String_Type
1372 (String_Type, In_Tree,
1373 To => First_String_Type_Of (Current_Project, In_Tree));
1374 Set_First_String_Type_Of
1375 (Current_Project, In_Tree, To => String_Type);
1376 end if;
1377 end if;
1379 -- Scan past the name
1381 Scan (In_Tree);
1382 end if;
1384 Expect (Tok_Is, "IS");
1386 if Token = Tok_Is then
1387 Scan (In_Tree);
1388 end if;
1390 Expect (Tok_Left_Paren, "`(`");
1392 if Token = Tok_Left_Paren then
1393 Scan (In_Tree);
1394 end if;
1396 Parse_String_Type_List
1397 (In_Tree => In_Tree, First_String => First_String, Flags => Flags);
1398 Set_First_Literal_String (String_Type, In_Tree, To => First_String);
1400 Expect (Tok_Right_Paren, "`)`");
1402 if Token = Tok_Right_Paren then
1403 Scan (In_Tree);
1404 end if;
1406 end Parse_String_Type_Declaration;
1408 --------------------------------
1409 -- Parse_Variable_Declaration --
1410 --------------------------------
1412 procedure Parse_Variable_Declaration
1413 (In_Tree : Project_Node_Tree_Ref;
1414 Variable : out Project_Node_Id;
1415 Current_Project : Project_Node_Id;
1416 Current_Package : Project_Node_Id;
1417 Flags : Processing_Flags)
1419 Expression_Location : Source_Ptr;
1420 String_Type_Name : Name_Id := No_Name;
1421 Project_String_Type_Name : Name_Id := No_Name;
1422 Type_Location : Source_Ptr := No_Location;
1423 Project_Location : Source_Ptr := No_Location;
1424 Expression : Project_Node_Id := Empty_Node;
1425 Variable_Name : constant Name_Id := Token_Name;
1426 OK : Boolean := True;
1428 begin
1429 Variable :=
1430 Default_Project_Node
1431 (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree);
1432 Set_Name_Of (Variable, In_Tree, To => Variable_Name);
1433 Set_Location_Of (Variable, In_Tree, To => Token_Ptr);
1435 -- Scan past the variable name
1437 Scan (In_Tree);
1439 if Token = Tok_Colon then
1441 -- Typed string variable declaration
1443 Scan (In_Tree);
1444 Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration);
1445 Expect (Tok_Identifier, "identifier");
1447 OK := Token = Tok_Identifier;
1449 if OK then
1450 String_Type_Name := Token_Name;
1451 Type_Location := Token_Ptr;
1452 Scan (In_Tree);
1454 if Token = Tok_Dot then
1455 Project_String_Type_Name := String_Type_Name;
1456 Project_Location := Type_Location;
1458 -- Scan past the dot
1460 Scan (In_Tree);
1461 Expect (Tok_Identifier, "identifier");
1463 if Token = Tok_Identifier then
1464 String_Type_Name := Token_Name;
1465 Type_Location := Token_Ptr;
1466 Scan (In_Tree);
1467 else
1468 OK := False;
1469 end if;
1470 end if;
1472 if OK then
1473 declare
1474 Proj : Project_Node_Id := Current_Project;
1475 Current : Project_Node_Id := Empty_Node;
1477 begin
1478 if Project_String_Type_Name /= No_Name then
1479 declare
1480 The_Project_Name_And_Node : constant
1481 Tree_Private_Part.Project_Name_And_Node :=
1482 Tree_Private_Part.Projects_Htable.Get
1483 (In_Tree.Projects_HT, Project_String_Type_Name);
1485 use Tree_Private_Part;
1487 begin
1488 if The_Project_Name_And_Node =
1489 Tree_Private_Part.No_Project_Name_And_Node
1490 then
1491 Error_Msg (Flags,
1492 "unknown project """ &
1493 Get_Name_String
1494 (Project_String_Type_Name) &
1495 """",
1496 Project_Location);
1497 Current := Empty_Node;
1498 else
1499 Current :=
1500 First_String_Type_Of
1501 (The_Project_Name_And_Node.Node, In_Tree);
1502 while
1503 Present (Current)
1504 and then
1505 Name_Of (Current, In_Tree) /= String_Type_Name
1506 loop
1507 Current := Next_String_Type (Current, In_Tree);
1508 end loop;
1509 end if;
1510 end;
1512 else
1513 -- Look for a string type with the correct name in this
1514 -- project or in any of its ancestors.
1516 loop
1517 Current :=
1518 First_String_Type_Of (Proj, In_Tree);
1519 while
1520 Present (Current)
1521 and then
1522 Name_Of (Current, In_Tree) /= String_Type_Name
1523 loop
1524 Current := Next_String_Type (Current, In_Tree);
1525 end loop;
1527 exit when Present (Current);
1529 Proj := Parent_Project_Of (Proj, In_Tree);
1530 exit when No (Proj);
1531 end loop;
1532 end if;
1534 if No (Current) then
1535 Error_Msg (Flags,
1536 "unknown string type """ &
1537 Get_Name_String (String_Type_Name) &
1538 """",
1539 Type_Location);
1540 OK := False;
1542 else
1543 Set_String_Type_Of
1544 (Variable, In_Tree, To => Current);
1545 end if;
1546 end;
1547 end if;
1548 end if;
1549 end if;
1551 Expect (Tok_Colon_Equal, "`:=`");
1553 OK := OK and then Token = Tok_Colon_Equal;
1555 if Token = Tok_Colon_Equal then
1556 Scan (In_Tree);
1557 end if;
1559 -- Get the single string or string list value
1561 Expression_Location := Token_Ptr;
1563 Parse_Expression
1564 (In_Tree => In_Tree,
1565 Expression => Expression,
1566 Flags => Flags,
1567 Current_Project => Current_Project,
1568 Current_Package => Current_Package,
1569 Optional_Index => False);
1570 Set_Expression_Of (Variable, In_Tree, To => Expression);
1572 if Present (Expression) then
1573 -- A typed string must have a single string value, not a list
1575 if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration
1576 and then Expression_Kind_Of (Expression, In_Tree) = List
1577 then
1578 Error_Msg
1579 (Flags,
1580 "expression must be a single string", Expression_Location);
1581 end if;
1583 Set_Expression_Kind_Of
1584 (Variable, In_Tree,
1585 To => Expression_Kind_Of (Expression, In_Tree));
1586 end if;
1588 if OK then
1589 declare
1590 The_Variable : Project_Node_Id := Empty_Node;
1592 begin
1593 if Present (Current_Package) then
1594 The_Variable := First_Variable_Of (Current_Package, In_Tree);
1595 elsif Present (Current_Project) then
1596 The_Variable := First_Variable_Of (Current_Project, In_Tree);
1597 end if;
1599 while Present (The_Variable)
1600 and then Name_Of (The_Variable, In_Tree) /= Variable_Name
1601 loop
1602 The_Variable := Next_Variable (The_Variable, In_Tree);
1603 end loop;
1605 if No (The_Variable) then
1606 if Present (Current_Package) then
1607 Set_Next_Variable
1608 (Variable, In_Tree,
1609 To => First_Variable_Of (Current_Package, In_Tree));
1610 Set_First_Variable_Of
1611 (Current_Package, In_Tree, To => Variable);
1613 elsif Present (Current_Project) then
1614 Set_Next_Variable
1615 (Variable, In_Tree,
1616 To => First_Variable_Of (Current_Project, In_Tree));
1617 Set_First_Variable_Of
1618 (Current_Project, In_Tree, To => Variable);
1619 end if;
1621 else
1622 if Expression_Kind_Of (Variable, In_Tree) /= Undefined then
1623 if Expression_Kind_Of (The_Variable, In_Tree) =
1624 Undefined
1625 then
1626 Set_Expression_Kind_Of
1627 (The_Variable, In_Tree,
1628 To => Expression_Kind_Of (Variable, In_Tree));
1630 else
1631 if Expression_Kind_Of (The_Variable, In_Tree) /=
1632 Expression_Kind_Of (Variable, In_Tree)
1633 then
1634 Error_Msg (Flags,
1635 "wrong expression kind for variable """ &
1636 Get_Name_String
1637 (Name_Of (The_Variable, In_Tree)) &
1638 """",
1639 Expression_Location);
1640 end if;
1641 end if;
1642 end if;
1643 end if;
1644 end;
1645 end if;
1646 end Parse_Variable_Declaration;
1648 end Prj.Dect;