PR target/16201
[official-gcc.git] / gcc / ada / prj-dect.adb
blobe030236afe8517f9ff8e9fba9fab1e52f857a413
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-2004 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Err_Vars; use Err_Vars;
28 with Namet; use Namet;
29 with Opt; use Opt;
30 with Prj.Err; use Prj.Err;
31 with Prj.Strt; use Prj.Strt;
32 with Prj.Tree; use Prj.Tree;
33 with Scans; use Scans;
34 with Snames;
35 with Types; use Types;
36 with Prj.Attr; use Prj.Attr;
37 with Prj.Attr.PM; use Prj.Attr.PM;
38 with Uintp; use Uintp;
40 package body Prj.Dect is
42 type Zone is (In_Project, In_Package, In_Case_Construction);
43 -- Used to indicate if we are parsing a package (In_Package),
44 -- a case construction (In_Case_Construction) or none of those two
45 -- (In_Project).
47 procedure Parse_Attribute_Declaration
48 (Attribute : out Project_Node_Id;
49 First_Attribute : Attribute_Node_Id;
50 Current_Project : Project_Node_Id;
51 Current_Package : Project_Node_Id);
52 -- Parse an attribute declaration.
54 procedure Parse_Case_Construction
55 (Case_Construction : out Project_Node_Id;
56 First_Attribute : Attribute_Node_Id;
57 Current_Project : Project_Node_Id;
58 Current_Package : Project_Node_Id);
59 -- Parse a case construction
61 procedure Parse_Declarative_Items
62 (Declarations : out Project_Node_Id;
63 In_Zone : Zone;
64 First_Attribute : Attribute_Node_Id;
65 Current_Project : Project_Node_Id;
66 Current_Package : Project_Node_Id);
67 -- Parse declarative items. Depending on In_Zone, some declarative
68 -- items may be forbiden.
70 procedure Parse_Package_Declaration
71 (Package_Declaration : out Project_Node_Id;
72 Current_Project : Project_Node_Id);
73 -- Parse a package declaration
75 procedure Parse_String_Type_Declaration
76 (String_Type : out Project_Node_Id;
77 Current_Project : Project_Node_Id);
78 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
80 procedure Parse_Variable_Declaration
81 (Variable : out Project_Node_Id;
82 Current_Project : Project_Node_Id;
83 Current_Package : Project_Node_Id);
84 -- Parse a variable assignment
85 -- <variable_Name> := <expression>; OR
86 -- <variable_Name> : <string_type_Name> := <string_expression>;
88 -----------
89 -- Parse --
90 -----------
92 procedure Parse
93 (Declarations : out Project_Node_Id;
94 Current_Project : Project_Node_Id;
95 Extends : Project_Node_Id)
97 First_Declarative_Item : Project_Node_Id := Empty_Node;
99 begin
100 Declarations := Default_Project_Node (Of_Kind => N_Project_Declaration);
101 Set_Location_Of (Declarations, To => Token_Ptr);
102 Set_Extended_Project_Of (Declarations, To => Extends);
103 Set_Project_Declaration_Of (Current_Project, Declarations);
104 Parse_Declarative_Items
105 (Declarations => First_Declarative_Item,
106 In_Zone => In_Project,
107 First_Attribute => Prj.Attr.Attribute_First,
108 Current_Project => Current_Project,
109 Current_Package => Empty_Node);
110 Set_First_Declarative_Item_Of
111 (Declarations, To => First_Declarative_Item);
112 end Parse;
114 ---------------------------------
115 -- Parse_Attribute_Declaration --
116 ---------------------------------
118 procedure Parse_Attribute_Declaration
119 (Attribute : out Project_Node_Id;
120 First_Attribute : Attribute_Node_Id;
121 Current_Project : Project_Node_Id;
122 Current_Package : Project_Node_Id)
124 Current_Attribute : Attribute_Node_Id := First_Attribute;
125 Full_Associative_Array : Boolean := False;
126 Attribute_Name : Name_Id := No_Name;
127 Optional_Index : Boolean := False;
128 Pkg_Id : Package_Node_Id := Empty_Package;
129 Warning : Boolean := False;
131 begin
132 Attribute := Default_Project_Node (Of_Kind => N_Attribute_Declaration);
133 Set_Location_Of (Attribute, To => Token_Ptr);
134 Set_Previous_Line_Node (Attribute);
136 -- Scan past "for"
138 Scan;
140 -- Body may be an attribute name
142 if Token = Tok_Body then
143 Token := Tok_Identifier;
144 Token_Name := Snames.Name_Body;
145 end if;
147 Expect (Tok_Identifier, "identifier");
149 if Token = Tok_Identifier then
150 Attribute_Name := Token_Name;
151 Set_Name_Of (Attribute, To => Token_Name);
152 Set_Location_Of (Attribute, To => Token_Ptr);
154 -- Find the attribute
156 Current_Attribute :=
157 Attribute_Node_Id_Of (Token_Name, First_Attribute);
159 -- If the attribute cannot be found, create the attribute if inside
160 -- an unknown package.
162 if Current_Attribute = Empty_Attribute then
163 if Current_Package /= Empty_Node
164 and then Expression_Kind_Of (Current_Package) = Ignored
165 then
166 Pkg_Id := Package_Id_Of (Current_Package);
167 Add_Attribute (Pkg_Id, Token_Name, Current_Attribute);
168 Error_Msg_Name_1 := Token_Name;
169 Error_Msg ("?unknown attribute {", Token_Ptr);
171 else
172 -- If not a valid attribute name, issue an error, or a warning
173 -- if inside a package that does not need to be checked.
175 Warning := Current_Package /= Empty_Node and then
176 Current_Packages_To_Check /= All_Packages;
178 if Warning then
180 -- Check that we are not in a package to check
182 Get_Name_String (Name_Of (Current_Package));
184 for Index in Current_Packages_To_Check'Range loop
185 if Name_Buffer (1 .. Name_Len) =
186 Current_Packages_To_Check (Index).all
187 then
188 Warning := False;
189 exit;
190 end if;
191 end loop;
192 end if;
194 Error_Msg_Name_1 := Token_Name;
196 if Warning then
197 Error_Msg ("?undefined attribute {", Token_Ptr);
199 else
200 Error_Msg ("undefined attribute {", Token_Ptr);
201 end if;
202 end if;
204 -- Set, if appropriate the index case insensitivity flag
206 elsif Attribute_Kind_Of (Current_Attribute) in
207 Case_Insensitive_Associative_Array ..
208 Optional_Index_Case_Insensitive_Associative_Array
209 then
210 Set_Case_Insensitive (Attribute, To => True);
211 end if;
213 Scan; -- past the attribute name
214 end if;
216 -- Change obsolete names of attributes to the new names
218 if Current_Package /= Empty_Node
219 and then Expression_Kind_Of (Current_Package) /= Ignored
220 then
221 case Name_Of (Attribute) is
222 when Snames.Name_Specification =>
223 Set_Name_Of (Attribute, To => Snames.Name_Spec);
225 when Snames.Name_Specification_Suffix =>
226 Set_Name_Of (Attribute, To => Snames.Name_Spec_Suffix);
228 when Snames.Name_Implementation =>
229 Set_Name_Of (Attribute, To => Snames.Name_Body);
231 when Snames.Name_Implementation_Suffix =>
232 Set_Name_Of (Attribute, To => Snames.Name_Body_Suffix);
234 when others =>
235 null;
236 end case;
237 end if;
239 -- Associative array attributes
241 if Token = Tok_Left_Paren then
243 -- If the attribute is not an associative array attribute, report
244 -- an error. If this information is still unknown, set the kind
245 -- to Associative_Array.
247 if Current_Attribute /= Empty_Attribute
248 and then Attribute_Kind_Of (Current_Attribute) = Single
249 then
250 Error_Msg ("the attribute """ &
251 Get_Name_String
252 (Attribute_Name_Of (Current_Attribute)) &
253 """ cannot be an associative array",
254 Location_Of (Attribute));
256 elsif Attribute_Kind_Of (Current_Attribute) = Unknown then
257 Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array);
258 end if;
260 Scan; -- past the left parenthesis
261 Expect (Tok_String_Literal, "literal string");
263 if Token = Tok_String_Literal then
264 Set_Associative_Array_Index_Of (Attribute, Token_Name);
265 Scan; -- past the literal string index
267 if Token = Tok_At then
268 case Attribute_Kind_Of (Current_Attribute) is
269 when Optional_Index_Associative_Array |
270 Optional_Index_Case_Insensitive_Associative_Array =>
271 Scan;
272 Expect (Tok_Integer_Literal, "integer literal");
274 if Token = Tok_Integer_Literal then
276 -- Set the source index value from given literal
278 declare
279 Index : constant Int :=
280 UI_To_Int (Int_Literal_Value);
281 begin
282 if Index = 0 then
283 Error_Msg ("index cannot be zero", Token_Ptr);
284 else
285 Set_Source_Index_Of (Attribute, To => Index);
286 end if;
287 end;
289 Scan;
290 end if;
292 when others =>
293 Error_Msg ("index not allowed here", Token_Ptr);
294 Scan;
296 if Token = Tok_Integer_Literal then
297 Scan;
298 end if;
299 end case;
300 end if;
301 end if;
303 Expect (Tok_Right_Paren, "`)`");
305 if Token = Tok_Right_Paren then
306 Scan; -- past the right parenthesis
307 end if;
309 else
310 -- If it is an associative array attribute and there are no left
311 -- parenthesis, then this is a full associative array declaration.
312 -- Flag it as such for later processing of its value.
314 if Current_Attribute /= Empty_Attribute
315 and then
316 Attribute_Kind_Of (Current_Attribute) /= Single
317 then
318 if Attribute_Kind_Of (Current_Attribute) = Unknown then
319 Set_Attribute_Kind_Of (Current_Attribute, To => Single);
321 else
322 Full_Associative_Array := True;
323 end if;
324 end if;
325 end if;
327 -- Set the expression kind of the attribute
329 if Current_Attribute /= Empty_Attribute then
330 Set_Expression_Kind_Of
331 (Attribute, To => Variable_Kind_Of (Current_Attribute));
332 Optional_Index := Optional_Index_Of (Current_Attribute);
333 end if;
335 Expect (Tok_Use, "USE");
337 if Token = Tok_Use then
338 Scan;
340 if Full_Associative_Array then
342 -- Expect <project>'<same_attribute_name>, or
343 -- <project>.<same_package_name>'<same_attribute_name>
345 declare
346 The_Project : Project_Node_Id := Empty_Node;
347 -- The node of the project where the associative array is
348 -- declared.
350 The_Package : Project_Node_Id := Empty_Node;
351 -- The node of the package where the associative array is
352 -- declared, if any.
354 Project_Name : Name_Id := No_Name;
355 -- The name of the project where the associative array is
356 -- declared.
358 Location : Source_Ptr := No_Location;
359 -- The location of the project name
361 begin
362 Expect (Tok_Identifier, "identifier");
364 if Token = Tok_Identifier then
365 Location := Token_Ptr;
367 -- Find the project node in the imported project or
368 -- in the project being extended.
370 The_Project := Imported_Or_Extended_Project_Of
371 (Current_Project, Token_Name);
373 if The_Project = Empty_Node then
374 Error_Msg ("unknown project", Location);
375 Scan; -- past the project name
377 else
378 Project_Name := Token_Name;
379 Scan; -- past the project name
381 -- If this is inside a package, a dot followed by the
382 -- name of the package must followed the project name.
384 if Current_Package /= Empty_Node then
385 Expect (Tok_Dot, "`.`");
387 if Token /= Tok_Dot then
388 The_Project := Empty_Node;
390 else
391 Scan; -- past the dot
392 Expect (Tok_Identifier, "identifier");
394 if Token /= Tok_Identifier then
395 The_Project := Empty_Node;
397 -- If it is not the same package name, issue error
399 elsif Token_Name /= Name_Of (Current_Package) then
400 The_Project := Empty_Node;
401 Error_Msg
402 ("not the same package as " &
403 Get_Name_String (Name_Of (Current_Package)),
404 Token_Ptr);
406 else
407 The_Package := First_Package_Of (The_Project);
409 -- Look for the package node
411 while The_Package /= Empty_Node
412 and then Name_Of (The_Package) /= Token_Name
413 loop
414 The_Package :=
415 Next_Package_In_Project (The_Package);
416 end loop;
418 -- If the package cannot be found in the
419 -- project, issue an error.
421 if The_Package = Empty_Node then
422 The_Project := Empty_Node;
423 Error_Msg_Name_2 := Project_Name;
424 Error_Msg_Name_1 := Token_Name;
425 Error_Msg
426 ("package % not declared in project %",
427 Token_Ptr);
428 end if;
430 Scan; -- past the package name
431 end if;
432 end if;
433 end if;
434 end if;
435 end if;
437 if The_Project /= Empty_Node then
439 -- Looking for '<same attribute name>
441 Expect (Tok_Apostrophe, "`''`");
443 if Token /= Tok_Apostrophe then
444 The_Project := Empty_Node;
446 else
447 Scan; -- past the apostrophe
448 Expect (Tok_Identifier, "identifier");
450 if Token /= Tok_Identifier then
451 The_Project := Empty_Node;
453 else
454 -- If it is not the same attribute name, issue error
456 if Token_Name /= Attribute_Name then
457 The_Project := Empty_Node;
458 Error_Msg_Name_1 := Attribute_Name;
459 Error_Msg ("invalid name, should be %", Token_Ptr);
460 end if;
462 Scan; -- past the attribute name
463 end if;
464 end if;
465 end if;
467 if The_Project = Empty_Node then
469 -- If there were any problem, set the attribute id to null,
470 -- so that the node will not be recorded.
472 Current_Attribute := Empty_Attribute;
474 else
475 -- Set the appropriate field in the node.
476 -- Note that the index and the expression are nil. This
477 -- characterizes full associative array attribute
478 -- declarations.
480 Set_Associative_Project_Of (Attribute, The_Project);
481 Set_Associative_Package_Of (Attribute, The_Package);
482 end if;
483 end;
485 -- Other attribute declarations (not full associative array)
487 else
488 declare
489 Expression_Location : constant Source_Ptr := Token_Ptr;
490 -- The location of the first token of the expression
492 Expression : Project_Node_Id := Empty_Node;
493 -- The expression, value for the attribute declaration
495 begin
496 -- Get the expression value and set it in the attribute node
498 Parse_Expression
499 (Expression => Expression,
500 Current_Project => Current_Project,
501 Current_Package => Current_Package,
502 Optional_Index => Optional_Index);
503 Set_Expression_Of (Attribute, To => Expression);
505 -- If the expression is legal, but not of the right kind
506 -- for the attribute, issue an error.
508 if Current_Attribute /= Empty_Attribute
509 and then Expression /= Empty_Node
510 and then Variable_Kind_Of (Current_Attribute) /=
511 Expression_Kind_Of (Expression)
512 then
513 if Variable_Kind_Of (Current_Attribute) = Undefined then
514 Set_Variable_Kind_Of
515 (Current_Attribute,
516 To => Expression_Kind_Of (Expression));
518 else
519 Error_Msg
520 ("wrong expression kind for attribute """ &
521 Get_Name_String
522 (Attribute_Name_Of (Current_Attribute)) &
523 """",
524 Expression_Location);
525 end if;
526 end if;
527 end;
528 end if;
529 end if;
531 -- If the attribute was not recognized, return an empty node.
532 -- It may be that it is not in a package to check, and the node will
533 -- not be added to the tree.
535 if Current_Attribute = Empty_Attribute then
536 Attribute := Empty_Node;
537 end if;
539 Set_End_Of_Line (Attribute);
540 Set_Previous_Line_Node (Attribute);
541 end Parse_Attribute_Declaration;
543 -----------------------------
544 -- Parse_Case_Construction --
545 -----------------------------
547 procedure Parse_Case_Construction
548 (Case_Construction : out Project_Node_Id;
549 First_Attribute : Attribute_Node_Id;
550 Current_Project : Project_Node_Id;
551 Current_Package : Project_Node_Id)
553 Current_Item : Project_Node_Id := Empty_Node;
554 Next_Item : Project_Node_Id := Empty_Node;
555 First_Case_Item : Boolean := True;
557 Variable_Location : Source_Ptr := No_Location;
559 String_Type : Project_Node_Id := Empty_Node;
561 Case_Variable : Project_Node_Id := Empty_Node;
563 First_Declarative_Item : Project_Node_Id := Empty_Node;
565 First_Choice : Project_Node_Id := Empty_Node;
567 When_Others : Boolean := False;
568 -- Set to True when there is a "when others =>" clause
570 begin
571 Case_Construction :=
572 Default_Project_Node (Of_Kind => N_Case_Construction);
573 Set_Location_Of (Case_Construction, To => Token_Ptr);
575 -- Scan past "case"
577 Scan;
579 -- Get the switch variable
581 Expect (Tok_Identifier, "identifier");
583 if Token = Tok_Identifier then
584 Variable_Location := Token_Ptr;
585 Parse_Variable_Reference
586 (Variable => Case_Variable,
587 Current_Project => Current_Project,
588 Current_Package => Current_Package);
589 Set_Case_Variable_Reference_Of
590 (Case_Construction, To => Case_Variable);
592 else
593 if Token /= Tok_Is then
594 Scan;
595 end if;
596 end if;
598 if Case_Variable /= Empty_Node then
599 String_Type := String_Type_Of (Case_Variable);
601 if String_Type = Empty_Node then
602 Error_Msg ("variable """ &
603 Get_Name_String (Name_Of (Case_Variable)) &
604 """ is not typed",
605 Variable_Location);
606 end if;
607 end if;
609 Expect (Tok_Is, "IS");
611 if Token = Tok_Is then
612 Set_End_Of_Line (Case_Construction);
613 Set_Previous_Line_Node (Case_Construction);
614 Set_Next_End_Node (Case_Construction);
616 -- Scan past "is"
618 Scan;
619 end if;
621 Start_New_Case_Construction (String_Type);
623 When_Loop :
625 while Token = Tok_When loop
627 if First_Case_Item then
628 Current_Item := Default_Project_Node (Of_Kind => N_Case_Item);
629 Set_First_Case_Item_Of (Case_Construction, To => Current_Item);
630 First_Case_Item := False;
632 else
633 Next_Item := Default_Project_Node (Of_Kind => N_Case_Item);
634 Set_Next_Case_Item (Current_Item, To => Next_Item);
635 Current_Item := Next_Item;
636 end if;
638 Set_Location_Of (Current_Item, To => Token_Ptr);
640 -- Scan past "when"
642 Scan;
644 if Token = Tok_Others then
645 When_Others := True;
647 -- Scan past "others"
649 Scan;
651 Expect (Tok_Arrow, "`=>`");
652 Set_End_Of_Line (Current_Item);
653 Set_Previous_Line_Node (Current_Item);
655 -- Empty_Node in Field1 of a Case_Item indicates
656 -- the "when others =>" branch.
658 Set_First_Choice_Of (Current_Item, To => Empty_Node);
660 Parse_Declarative_Items
661 (Declarations => First_Declarative_Item,
662 In_Zone => In_Case_Construction,
663 First_Attribute => First_Attribute,
664 Current_Project => Current_Project,
665 Current_Package => Current_Package);
667 -- "when others =>" must be the last branch, so save the
668 -- Case_Item and exit
670 Set_First_Declarative_Item_Of
671 (Current_Item, To => First_Declarative_Item);
672 exit When_Loop;
674 else
675 Parse_Choice_List (First_Choice => First_Choice);
676 Set_First_Choice_Of (Current_Item, To => First_Choice);
678 Expect (Tok_Arrow, "`=>`");
679 Set_End_Of_Line (Current_Item);
680 Set_Previous_Line_Node (Current_Item);
682 Parse_Declarative_Items
683 (Declarations => First_Declarative_Item,
684 In_Zone => In_Case_Construction,
685 First_Attribute => First_Attribute,
686 Current_Project => Current_Project,
687 Current_Package => Current_Package);
689 Set_First_Declarative_Item_Of
690 (Current_Item, To => First_Declarative_Item);
692 end if;
693 end loop When_Loop;
695 End_Case_Construction
696 (Check_All_Labels => not When_Others and not Quiet_Output,
697 Case_Location => Location_Of (Case_Construction));
699 Expect (Tok_End, "`END CASE`");
700 Remove_Next_End_Node;
702 if Token = Tok_End then
704 -- Scan past "end"
706 Scan;
708 Expect (Tok_Case, "CASE");
710 end if;
712 -- Scan past "case"
714 Scan;
716 Expect (Tok_Semicolon, "`;`");
717 Set_Previous_End_Node (Case_Construction);
719 end Parse_Case_Construction;
721 -----------------------------
722 -- Parse_Declarative_Items --
723 -----------------------------
725 procedure Parse_Declarative_Items
726 (Declarations : out Project_Node_Id;
727 In_Zone : Zone;
728 First_Attribute : Attribute_Node_Id;
729 Current_Project : Project_Node_Id;
730 Current_Package : Project_Node_Id)
732 Current_Declarative_Item : Project_Node_Id := Empty_Node;
733 Next_Declarative_Item : Project_Node_Id := Empty_Node;
734 Current_Declaration : Project_Node_Id := Empty_Node;
735 Item_Location : Source_Ptr := No_Location;
737 begin
738 Declarations := Empty_Node;
740 loop
741 -- We are always positioned at the token that precedes
742 -- the first token of the declarative element.
743 -- Scan past it
745 Scan;
747 Item_Location := Token_Ptr;
749 case Token is
750 when Tok_Identifier =>
752 if In_Zone = In_Case_Construction then
753 Error_Msg ("a variable cannot be declared here",
754 Token_Ptr);
755 end if;
757 Parse_Variable_Declaration
758 (Current_Declaration,
759 Current_Project => Current_Project,
760 Current_Package => Current_Package);
762 Set_End_Of_Line (Current_Declaration);
763 Set_Previous_Line_Node (Current_Declaration);
765 when Tok_For =>
767 Parse_Attribute_Declaration
768 (Attribute => Current_Declaration,
769 First_Attribute => First_Attribute,
770 Current_Project => Current_Project,
771 Current_Package => Current_Package);
773 Set_End_Of_Line (Current_Declaration);
774 Set_Previous_Line_Node (Current_Declaration);
776 when Tok_Null =>
778 Scan; -- past "null"
780 when Tok_Package =>
782 -- Package declaration
784 if In_Zone /= In_Project then
785 Error_Msg ("a package cannot be declared here", Token_Ptr);
786 end if;
788 Parse_Package_Declaration
789 (Package_Declaration => Current_Declaration,
790 Current_Project => Current_Project);
792 Set_Previous_End_Node (Current_Declaration);
794 when Tok_Type =>
796 -- Type String Declaration
798 if In_Zone /= In_Project then
799 Error_Msg ("a string type cannot be declared here",
800 Token_Ptr);
801 end if;
803 Parse_String_Type_Declaration
804 (String_Type => Current_Declaration,
805 Current_Project => Current_Project);
807 Set_End_Of_Line (Current_Declaration);
808 Set_Previous_Line_Node (Current_Declaration);
810 when Tok_Case =>
812 -- Case construction
814 Parse_Case_Construction
815 (Case_Construction => Current_Declaration,
816 First_Attribute => First_Attribute,
817 Current_Project => Current_Project,
818 Current_Package => Current_Package);
820 Set_Previous_End_Node (Current_Declaration);
822 when others =>
823 exit;
825 -- We are leaving Parse_Declarative_Items positionned
826 -- at the first token after the list of declarative items.
827 -- It could be "end" (for a project, a package declaration or
828 -- a case construction) or "when" (for a case construction)
830 end case;
832 Expect (Tok_Semicolon, "`;` after declarative items");
834 -- Insert an N_Declarative_Item in the tree, but only if
835 -- Current_Declaration is not an empty node.
837 if Current_Declaration /= Empty_Node then
838 if Current_Declarative_Item = Empty_Node then
839 Current_Declarative_Item :=
840 Default_Project_Node (Of_Kind => N_Declarative_Item);
841 Declarations := Current_Declarative_Item;
843 else
844 Next_Declarative_Item :=
845 Default_Project_Node (Of_Kind => N_Declarative_Item);
846 Set_Next_Declarative_Item
847 (Current_Declarative_Item, To => Next_Declarative_Item);
848 Current_Declarative_Item := Next_Declarative_Item;
849 end if;
851 Set_Current_Item_Node
852 (Current_Declarative_Item, To => Current_Declaration);
853 Set_Location_Of (Current_Declarative_Item, To => Item_Location);
854 end if;
856 end loop;
858 end Parse_Declarative_Items;
860 -------------------------------
861 -- Parse_Package_Declaration --
862 -------------------------------
864 procedure Parse_Package_Declaration
865 (Package_Declaration : out Project_Node_Id;
866 Current_Project : Project_Node_Id)
868 First_Attribute : Attribute_Node_Id := Empty_Attribute;
869 Current_Package : Package_Node_Id := Empty_Package;
870 First_Declarative_Item : Project_Node_Id := Empty_Node;
872 begin
873 Package_Declaration :=
874 Default_Project_Node (Of_Kind => N_Package_Declaration);
875 Set_Location_Of (Package_Declaration, To => Token_Ptr);
877 -- Scan past "package"
879 Scan;
880 Expect (Tok_Identifier, "identifier");
882 if Token = Tok_Identifier then
884 Set_Name_Of (Package_Declaration, To => Token_Name);
886 Current_Package := Package_Node_Id_Of (Token_Name);
888 if Current_Package /= Empty_Package then
889 First_Attribute := First_Attribute_Of (Current_Package);
891 else
892 Error_Msg ("?""" &
893 Get_Name_String (Name_Of (Package_Declaration)) &
894 """ is not a known package name",
895 Token_Ptr);
897 -- Set the package declaration to "ignored" so that it is not
898 -- processed by Prj.Proc.Process.
900 Set_Expression_Kind_Of (Package_Declaration, Ignored);
902 -- Add the unknown package in the list of packages
904 Add_Unknown_Package (Token_Name, Current_Package);
905 end if;
907 Set_Package_Id_Of (Package_Declaration, To => Current_Package);
909 declare
910 Current : Project_Node_Id := First_Package_Of (Current_Project);
912 begin
913 while Current /= Empty_Node
914 and then Name_Of (Current) /= Token_Name
915 loop
916 Current := Next_Package_In_Project (Current);
917 end loop;
919 if Current /= Empty_Node then
920 Error_Msg
921 ("package """ &
922 Get_Name_String (Name_Of (Package_Declaration)) &
923 """ is declared twice in the same project",
924 Token_Ptr);
926 else
927 -- Add the package to the project list
929 Set_Next_Package_In_Project
930 (Package_Declaration,
931 To => First_Package_Of (Current_Project));
932 Set_First_Package_Of
933 (Current_Project, To => Package_Declaration);
934 end if;
935 end;
937 -- Scan past the package name
939 Scan;
940 end if;
942 if Token = Tok_Renames then
944 -- Scan past "renames"
946 Scan;
948 Expect (Tok_Identifier, "identifier");
950 if Token = Tok_Identifier then
951 declare
952 Project_Name : constant Name_Id := Token_Name;
953 Clause : Project_Node_Id :=
954 First_With_Clause_Of (Current_Project);
955 The_Project : Project_Node_Id := Empty_Node;
956 Extended : constant Project_Node_Id :=
957 Extended_Project_Of
958 (Project_Declaration_Of (Current_Project));
959 begin
960 while Clause /= Empty_Node loop
961 -- Only non limited imported projects may be used
962 -- in a renames declaration.
964 The_Project := Non_Limited_Project_Node_Of (Clause);
965 exit when The_Project /= Empty_Node
966 and then Name_Of (The_Project) = Project_Name;
967 Clause := Next_With_Clause_Of (Clause);
968 end loop;
970 if Clause = Empty_Node then
971 -- As we have not found the project in the imports, we check
972 -- if it's the name of an eventual extended project.
974 if Extended /= Empty_Node
975 and then Name_Of (Extended) = Project_Name then
976 Set_Project_Of_Renamed_Package_Of
977 (Package_Declaration, To => Extended);
978 else
979 Error_Msg_Name_1 := Project_Name;
980 Error_Msg
981 ("% is not an imported or extended project", Token_Ptr);
982 end if;
983 else
984 Set_Project_Of_Renamed_Package_Of
985 (Package_Declaration, To => The_Project);
986 end if;
987 end;
989 Scan;
990 Expect (Tok_Dot, "`.`");
992 if Token = Tok_Dot then
993 Scan;
994 Expect (Tok_Identifier, "identifier");
996 if Token = Tok_Identifier then
997 if Name_Of (Package_Declaration) /= Token_Name then
998 Error_Msg ("not the same package name", Token_Ptr);
999 elsif
1000 Project_Of_Renamed_Package_Of (Package_Declaration)
1001 /= Empty_Node
1002 then
1003 declare
1004 Current : Project_Node_Id :=
1005 First_Package_Of
1006 (Project_Of_Renamed_Package_Of
1007 (Package_Declaration));
1009 begin
1010 while Current /= Empty_Node
1011 and then Name_Of (Current) /= Token_Name
1012 loop
1013 Current := Next_Package_In_Project (Current);
1014 end loop;
1016 if Current = Empty_Node then
1017 Error_Msg
1018 ("""" &
1019 Get_Name_String (Token_Name) &
1020 """ is not a package declared by the project",
1021 Token_Ptr);
1022 end if;
1023 end;
1024 end if;
1026 Scan;
1027 end if;
1028 end if;
1029 end if;
1031 Expect (Tok_Semicolon, "`;`");
1032 Set_End_Of_Line (Package_Declaration);
1033 Set_Previous_Line_Node (Package_Declaration);
1035 elsif Token = Tok_Is then
1036 Set_End_Of_Line (Package_Declaration);
1037 Set_Previous_Line_Node (Package_Declaration);
1038 Set_Next_End_Node (Package_Declaration);
1040 Parse_Declarative_Items
1041 (Declarations => First_Declarative_Item,
1042 In_Zone => In_Package,
1043 First_Attribute => First_Attribute,
1044 Current_Project => Current_Project,
1045 Current_Package => Package_Declaration);
1047 Set_First_Declarative_Item_Of
1048 (Package_Declaration, To => First_Declarative_Item);
1050 Expect (Tok_End, "END");
1052 if Token = Tok_End then
1054 -- Scan past "end"
1056 Scan;
1057 end if;
1059 -- We should have the name of the package after "end"
1061 Expect (Tok_Identifier, "identifier");
1063 if Token = Tok_Identifier
1064 and then Name_Of (Package_Declaration) /= No_Name
1065 and then Token_Name /= Name_Of (Package_Declaration)
1066 then
1067 Error_Msg_Name_1 := Name_Of (Package_Declaration);
1068 Error_Msg ("expected {", Token_Ptr);
1069 end if;
1071 if Token /= Tok_Semicolon then
1073 -- Scan past the package name
1075 Scan;
1076 end if;
1078 Expect (Tok_Semicolon, "`;`");
1079 Remove_Next_End_Node;
1081 else
1082 Error_Msg ("expected IS or RENAMES", Token_Ptr);
1083 end if;
1085 end Parse_Package_Declaration;
1087 -----------------------------------
1088 -- Parse_String_Type_Declaration --
1089 -----------------------------------
1091 procedure Parse_String_Type_Declaration
1092 (String_Type : out Project_Node_Id;
1093 Current_Project : Project_Node_Id)
1095 Current : Project_Node_Id := Empty_Node;
1096 First_String : Project_Node_Id := Empty_Node;
1098 begin
1099 String_Type :=
1100 Default_Project_Node (Of_Kind => N_String_Type_Declaration);
1102 Set_Location_Of (String_Type, To => Token_Ptr);
1104 -- Scan past "type"
1106 Scan;
1108 Expect (Tok_Identifier, "identifier");
1110 if Token = Tok_Identifier then
1111 Set_Name_Of (String_Type, To => Token_Name);
1113 Current := First_String_Type_Of (Current_Project);
1114 while Current /= Empty_Node
1115 and then
1116 Name_Of (Current) /= Token_Name
1117 loop
1118 Current := Next_String_Type (Current);
1119 end loop;
1121 if Current /= Empty_Node then
1122 Error_Msg ("duplicate string type name """ &
1123 Get_Name_String (Token_Name) &
1124 """",
1125 Token_Ptr);
1126 else
1127 Current := First_Variable_Of (Current_Project);
1128 while Current /= Empty_Node
1129 and then Name_Of (Current) /= Token_Name
1130 loop
1131 Current := Next_Variable (Current);
1132 end loop;
1134 if Current /= Empty_Node then
1135 Error_Msg ("""" &
1136 Get_Name_String (Token_Name) &
1137 """ is already a variable name", Token_Ptr);
1138 else
1139 Set_Next_String_Type
1140 (String_Type, To => First_String_Type_Of (Current_Project));
1141 Set_First_String_Type_Of (Current_Project, To => String_Type);
1142 end if;
1143 end if;
1145 -- Scan past the name
1147 Scan;
1148 end if;
1150 Expect (Tok_Is, "IS");
1152 if Token = Tok_Is then
1153 Scan;
1154 end if;
1156 Expect (Tok_Left_Paren, "`(`");
1158 if Token = Tok_Left_Paren then
1159 Scan;
1160 end if;
1162 Parse_String_Type_List (First_String => First_String);
1163 Set_First_Literal_String (String_Type, To => First_String);
1165 Expect (Tok_Right_Paren, "`)`");
1167 if Token = Tok_Right_Paren then
1168 Scan;
1169 end if;
1171 end Parse_String_Type_Declaration;
1173 --------------------------------
1174 -- Parse_Variable_Declaration --
1175 --------------------------------
1177 procedure Parse_Variable_Declaration
1178 (Variable : out Project_Node_Id;
1179 Current_Project : Project_Node_Id;
1180 Current_Package : Project_Node_Id)
1182 Expression_Location : Source_Ptr;
1183 String_Type_Name : Name_Id := No_Name;
1184 Project_String_Type_Name : Name_Id := No_Name;
1185 Type_Location : Source_Ptr := No_Location;
1186 Project_Location : Source_Ptr := No_Location;
1187 Expression : Project_Node_Id := Empty_Node;
1188 Variable_Name : constant Name_Id := Token_Name;
1189 OK : Boolean := True;
1191 begin
1192 Variable :=
1193 Default_Project_Node (Of_Kind => N_Variable_Declaration);
1194 Set_Name_Of (Variable, To => Variable_Name);
1195 Set_Location_Of (Variable, To => Token_Ptr);
1197 -- Scan past the variable name
1199 Scan;
1201 if Token = Tok_Colon then
1203 -- Typed string variable declaration
1205 Scan;
1206 Set_Kind_Of (Variable, N_Typed_Variable_Declaration);
1207 Expect (Tok_Identifier, "identifier");
1209 OK := Token = Tok_Identifier;
1211 if OK then
1212 String_Type_Name := Token_Name;
1213 Type_Location := Token_Ptr;
1214 Scan;
1216 if Token = Tok_Dot then
1217 Project_String_Type_Name := String_Type_Name;
1218 Project_Location := Type_Location;
1220 -- Scan past the dot
1222 Scan;
1223 Expect (Tok_Identifier, "identifier");
1225 if Token = Tok_Identifier then
1226 String_Type_Name := Token_Name;
1227 Type_Location := Token_Ptr;
1228 Scan;
1229 else
1230 OK := False;
1231 end if;
1232 end if;
1234 if OK then
1235 declare
1236 Current : Project_Node_Id :=
1237 First_String_Type_Of (Current_Project);
1239 begin
1240 if Project_String_Type_Name /= No_Name then
1241 declare
1242 The_Project_Name_And_Node : constant
1243 Tree_Private_Part.Project_Name_And_Node :=
1244 Tree_Private_Part.Projects_Htable.Get
1245 (Project_String_Type_Name);
1247 use Tree_Private_Part;
1249 begin
1250 if The_Project_Name_And_Node =
1251 Tree_Private_Part.No_Project_Name_And_Node
1252 then
1253 Error_Msg ("unknown project """ &
1254 Get_Name_String
1255 (Project_String_Type_Name) &
1256 """",
1257 Project_Location);
1258 Current := Empty_Node;
1259 else
1260 Current :=
1261 First_String_Type_Of
1262 (The_Project_Name_And_Node.Node);
1263 end if;
1264 end;
1265 end if;
1267 while Current /= Empty_Node
1268 and then Name_Of (Current) /= String_Type_Name
1269 loop
1270 Current := Next_String_Type (Current);
1271 end loop;
1273 if Current = Empty_Node then
1274 Error_Msg ("unknown string type """ &
1275 Get_Name_String (String_Type_Name) &
1276 """",
1277 Type_Location);
1278 OK := False;
1279 else
1280 Set_String_Type_Of
1281 (Variable, To => Current);
1282 end if;
1283 end;
1284 end if;
1285 end if;
1286 end if;
1288 Expect (Tok_Colon_Equal, "`:=`");
1290 OK := OK and (Token = Tok_Colon_Equal);
1292 if Token = Tok_Colon_Equal then
1293 Scan;
1294 end if;
1296 -- Get the single string or string list value
1298 Expression_Location := Token_Ptr;
1300 Parse_Expression
1301 (Expression => Expression,
1302 Current_Project => Current_Project,
1303 Current_Package => Current_Package,
1304 Optional_Index => False);
1305 Set_Expression_Of (Variable, To => Expression);
1307 if Expression /= Empty_Node then
1308 -- A typed string must have a single string value, not a list
1310 if Kind_Of (Variable) = N_Typed_Variable_Declaration
1311 and then Expression_Kind_Of (Expression) = List
1312 then
1313 Error_Msg
1314 ("expression must be a single string", Expression_Location);
1315 end if;
1317 Set_Expression_Kind_Of
1318 (Variable, To => Expression_Kind_Of (Expression));
1319 end if;
1321 if OK then
1322 declare
1323 The_Variable : Project_Node_Id := Empty_Node;
1325 begin
1326 if Current_Package /= Empty_Node then
1327 The_Variable := First_Variable_Of (Current_Package);
1328 elsif Current_Project /= Empty_Node then
1329 The_Variable := First_Variable_Of (Current_Project);
1330 end if;
1332 while The_Variable /= Empty_Node
1333 and then Name_Of (The_Variable) /= Variable_Name
1334 loop
1335 The_Variable := Next_Variable (The_Variable);
1336 end loop;
1338 if The_Variable = Empty_Node then
1339 if Current_Package /= Empty_Node then
1340 Set_Next_Variable
1341 (Variable, To => First_Variable_Of (Current_Package));
1342 Set_First_Variable_Of (Current_Package, To => Variable);
1344 elsif Current_Project /= Empty_Node then
1345 Set_Next_Variable
1346 (Variable, To => First_Variable_Of (Current_Project));
1347 Set_First_Variable_Of (Current_Project, To => Variable);
1348 end if;
1350 else
1351 if Expression_Kind_Of (Variable) /= Undefined then
1352 if Expression_Kind_Of (The_Variable) = Undefined then
1353 Set_Expression_Kind_Of
1354 (The_Variable, To => Expression_Kind_Of (Variable));
1356 else
1357 if Expression_Kind_Of (The_Variable) /=
1358 Expression_Kind_Of (Variable)
1359 then
1360 Error_Msg ("wrong expression kind for variable """ &
1361 Get_Name_String (Name_Of (The_Variable)) &
1362 """",
1363 Expression_Location);
1364 end if;
1365 end if;
1366 end if;
1367 end if;
1368 end;
1369 end if;
1371 end Parse_Variable_Declaration;
1373 end Prj.Dect;