1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2004 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 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. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Err_Vars
; use Err_Vars
;
28 with Namet
; use Namet
;
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
;
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
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
;
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>;
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
;
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
);
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;
132 Attribute
:= Default_Project_Node
(Of_Kind
=> N_Attribute_Declaration
);
133 Set_Location_Of
(Attribute
, To
=> Token_Ptr
);
134 Set_Previous_Line_Node
(Attribute
);
140 -- Body may be an attribute name
142 if Token
= Tok_Body
then
143 Token
:= Tok_Identifier
;
144 Token_Name
:= Snames
.Name_Body
;
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
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
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
);
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
;
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
194 Error_Msg_Name_1
:= Token_Name
;
197 Error_Msg
("?undefined attribute {", Token_Ptr
);
200 Error_Msg
("undefined attribute {", Token_Ptr
);
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
210 Set_Case_Insensitive
(Attribute
, To
=> True);
213 Scan
; -- past the attribute name
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
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
);
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
250 Error_Msg
("the attribute """ &
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
);
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
=>
272 Expect
(Tok_Integer_Literal
, "integer literal");
274 if Token
= Tok_Integer_Literal
then
276 -- Set the source index value from given literal
279 Index
: constant Int
:=
280 UI_To_Int
(Int_Literal_Value
);
283 Error_Msg
("index cannot be zero", Token_Ptr
);
285 Set_Source_Index_Of
(Attribute
, To
=> Index
);
293 Error_Msg
("index not allowed here", Token_Ptr
);
296 if Token
= Tok_Integer_Literal
then
303 Expect
(Tok_Right_Paren
, "`)`");
305 if Token
= Tok_Right_Paren
then
306 Scan
; -- past the right parenthesis
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
316 Attribute_Kind_Of
(Current_Attribute
) /= Single
318 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
319 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
322 Full_Associative_Array
:= True;
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
);
335 Expect
(Tok_Use
, "USE");
337 if Token
= Tok_Use
then
340 if Full_Associative_Array
then
342 -- Expect <project>'<same_attribute_name>, or
343 -- <project>.<same_package_name>'<same_attribute_name>
346 The_Project
: Project_Node_Id
:= Empty_Node
;
347 -- The node of the project where the associative array is
350 The_Package
: Project_Node_Id
:= Empty_Node
;
351 -- The node of the package where the associative array is
354 Project_Name
: Name_Id
:= No_Name
;
355 -- The name of the project where the associative array is
358 Location
: Source_Ptr
:= No_Location
;
359 -- The location of the project name
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
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
;
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
;
402 ("not the same package as " &
403 Get_Name_String
(Name_Of
(Current_Package
)),
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
415 Next_Package_In_Project
(The_Package
);
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
;
426 ("package % not declared in project %",
430 Scan
; -- past the package name
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
;
447 Scan
; -- past the apostrophe
448 Expect
(Tok_Identifier
, "identifier");
450 if Token
/= Tok_Identifier
then
451 The_Project
:= Empty_Node
;
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
);
462 Scan
; -- past the attribute name
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
;
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
480 Set_Associative_Project_Of
(Attribute
, The_Project
);
481 Set_Associative_Package_Of
(Attribute
, The_Package
);
485 -- Other attribute declarations (not full associative array)
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
496 -- Get the expression value and set it in the attribute node
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
)
513 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
516 To
=> Expression_Kind_Of
(Expression
));
520 ("wrong expression kind for attribute """ &
522 (Attribute_Name_Of
(Current_Attribute
)) &
524 Expression_Location
);
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
;
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
572 Default_Project_Node
(Of_Kind
=> N_Case_Construction
);
573 Set_Location_Of
(Case_Construction
, To
=> Token_Ptr
);
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
);
593 if Token
/= Tok_Is
then
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
)) &
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
);
621 Start_New_Case_Construction
(String_Type
);
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;
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
;
638 Set_Location_Of
(Current_Item
, To
=> Token_Ptr
);
644 if Token
= Tok_Others
then
647 -- Scan past "others"
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
);
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
);
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
708 Expect
(Tok_Case
, "CASE");
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
;
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
;
738 Declarations
:= Empty_Node
;
741 -- We are always positioned at the token that precedes
742 -- the first token of the declarative element.
747 Item_Location
:= Token_Ptr
;
750 when Tok_Identifier
=>
752 if In_Zone
= In_Case_Construction
then
753 Error_Msg
("a variable cannot be declared here",
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
);
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
);
782 -- Package declaration
784 if In_Zone
/= In_Project
then
785 Error_Msg
("a package cannot be declared here", Token_Ptr
);
788 Parse_Package_Declaration
789 (Package_Declaration
=> Current_Declaration
,
790 Current_Project
=> Current_Project
);
792 Set_Previous_End_Node
(Current_Declaration
);
796 -- Type String Declaration
798 if In_Zone
/= In_Project
then
799 Error_Msg
("a string type cannot be declared here",
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
);
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
);
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)
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
;
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
;
851 Set_Current_Item_Node
852 (Current_Declarative_Item
, To
=> Current_Declaration
);
853 Set_Location_Of
(Current_Declarative_Item
, To
=> Item_Location
);
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
;
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"
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
);
893 Get_Name_String
(Name_Of
(Package_Declaration
)) &
894 """ is not a known package name",
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
);
907 Set_Package_Id_Of
(Package_Declaration
, To
=> Current_Package
);
910 Current
: Project_Node_Id
:= First_Package_Of
(Current_Project
);
913 while Current
/= Empty_Node
914 and then Name_Of
(Current
) /= Token_Name
916 Current
:= Next_Package_In_Project
(Current
);
919 if Current
/= Empty_Node
then
922 Get_Name_String
(Name_Of
(Package_Declaration
)) &
923 """ is declared twice in the same project",
927 -- Add the package to the project list
929 Set_Next_Package_In_Project
930 (Package_Declaration
,
931 To
=> First_Package_Of
(Current_Project
));
933 (Current_Project
, To
=> Package_Declaration
);
937 -- Scan past the package name
942 if Token
= Tok_Renames
then
944 -- Scan past "renames"
948 Expect
(Tok_Identifier
, "identifier");
950 if Token
= Tok_Identifier
then
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
:=
958 (Project_Declaration_Of
(Current_Project
));
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
);
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
);
979 Error_Msg_Name_1
:= Project_Name
;
981 ("% is not an imported or extended project", Token_Ptr
);
984 Set_Project_Of_Renamed_Package_Of
985 (Package_Declaration
, To
=> The_Project
);
990 Expect
(Tok_Dot
, "`.`");
992 if Token
= Tok_Dot
then
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
);
1000 Project_Of_Renamed_Package_Of
(Package_Declaration
)
1004 Current
: Project_Node_Id
:=
1006 (Project_Of_Renamed_Package_Of
1007 (Package_Declaration
));
1010 while Current
/= Empty_Node
1011 and then Name_Of
(Current
) /= Token_Name
1013 Current
:= Next_Package_In_Project
(Current
);
1016 if Current
= Empty_Node
then
1019 Get_Name_String
(Token_Name
) &
1020 """ is not a package declared by the project",
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
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
)
1067 Error_Msg_Name_1
:= Name_Of
(Package_Declaration
);
1068 Error_Msg
("expected {", Token_Ptr
);
1071 if Token
/= Tok_Semicolon
then
1073 -- Scan past the package name
1078 Expect
(Tok_Semicolon
, "`;`");
1079 Remove_Next_End_Node
;
1082 Error_Msg
("expected IS or RENAMES", Token_Ptr
);
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
;
1100 Default_Project_Node
(Of_Kind
=> N_String_Type_Declaration
);
1102 Set_Location_Of
(String_Type
, To
=> Token_Ptr
);
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
1116 Name_Of
(Current
) /= Token_Name
1118 Current
:= Next_String_Type
(Current
);
1121 if Current
/= Empty_Node
then
1122 Error_Msg
("duplicate string type name """ &
1123 Get_Name_String
(Token_Name
) &
1127 Current
:= First_Variable_Of
(Current_Project
);
1128 while Current
/= Empty_Node
1129 and then Name_Of
(Current
) /= Token_Name
1131 Current
:= Next_Variable
(Current
);
1134 if Current
/= Empty_Node
then
1136 Get_Name_String
(Token_Name
) &
1137 """ is already a variable name", Token_Ptr
);
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
);
1145 -- Scan past the name
1150 Expect
(Tok_Is
, "IS");
1152 if Token
= Tok_Is
then
1156 Expect
(Tok_Left_Paren
, "`(`");
1158 if Token
= Tok_Left_Paren
then
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
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;
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
1201 if Token
= Tok_Colon
then
1203 -- Typed string variable declaration
1206 Set_Kind_Of
(Variable
, N_Typed_Variable_Declaration
);
1207 Expect
(Tok_Identifier
, "identifier");
1209 OK
:= Token
= Tok_Identifier
;
1212 String_Type_Name
:= Token_Name
;
1213 Type_Location
:= Token_Ptr
;
1216 if Token
= Tok_Dot
then
1217 Project_String_Type_Name
:= String_Type_Name
;
1218 Project_Location
:= Type_Location
;
1220 -- Scan past the dot
1223 Expect
(Tok_Identifier
, "identifier");
1225 if Token
= Tok_Identifier
then
1226 String_Type_Name
:= Token_Name
;
1227 Type_Location
:= Token_Ptr
;
1236 Current
: Project_Node_Id
:=
1237 First_String_Type_Of
(Current_Project
);
1240 if Project_String_Type_Name
/= No_Name
then
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
;
1250 if The_Project_Name_And_Node
=
1251 Tree_Private_Part
.No_Project_Name_And_Node
1253 Error_Msg
("unknown project """ &
1255 (Project_String_Type_Name
) &
1258 Current
:= Empty_Node
;
1261 First_String_Type_Of
1262 (The_Project_Name_And_Node
.Node
);
1267 while Current
/= Empty_Node
1268 and then Name_Of
(Current
) /= String_Type_Name
1270 Current
:= Next_String_Type
(Current
);
1273 if Current
= Empty_Node
then
1274 Error_Msg
("unknown string type """ &
1275 Get_Name_String
(String_Type_Name
) &
1281 (Variable
, To
=> Current
);
1288 Expect
(Tok_Colon_Equal
, "`:=`");
1290 OK
:= OK
and (Token
= Tok_Colon_Equal
);
1292 if Token
= Tok_Colon_Equal
then
1296 -- Get the single string or string list value
1298 Expression_Location
:= Token_Ptr
;
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
1314 ("expression must be a single string", Expression_Location
);
1317 Set_Expression_Kind_Of
1318 (Variable
, To
=> Expression_Kind_Of
(Expression
));
1323 The_Variable
: Project_Node_Id
:= Empty_Node
;
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
);
1332 while The_Variable
/= Empty_Node
1333 and then Name_Of
(The_Variable
) /= Variable_Name
1335 The_Variable
:= Next_Variable
(The_Variable
);
1338 if The_Variable
= Empty_Node
then
1339 if Current_Package
/= Empty_Node
then
1341 (Variable
, To
=> First_Variable_Of
(Current_Package
));
1342 Set_First_Variable_Of
(Current_Package
, To
=> Variable
);
1344 elsif Current_Project
/= Empty_Node
then
1346 (Variable
, To
=> First_Variable_Of
(Current_Project
));
1347 Set_First_Variable_Of
(Current_Project
, To
=> Variable
);
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
));
1357 if Expression_Kind_Of
(The_Variable
) /=
1358 Expression_Kind_Of
(Variable
)
1360 Error_Msg
("wrong expression kind for variable """ &
1361 Get_Name_String
(Name_Of
(The_Variable
)) &
1363 Expression_Location
);
1371 end Parse_Variable_Declaration
;