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 Uintp
; use Uintp
;
39 package body Prj
.Dect
is
41 type Zone
is (In_Project
, In_Package
, In_Case_Construction
);
42 -- Used to indicate if we are parsing a package (In_Package),
43 -- a case construction (In_Case_Construction) or none of those two
46 procedure Parse_Attribute_Declaration
47 (Attribute
: out Project_Node_Id
;
48 First_Attribute
: Attribute_Node_Id
;
49 Current_Project
: Project_Node_Id
;
50 Current_Package
: Project_Node_Id
);
51 -- Parse an attribute declaration.
53 procedure Parse_Case_Construction
54 (Case_Construction
: out Project_Node_Id
;
55 First_Attribute
: Attribute_Node_Id
;
56 Current_Project
: Project_Node_Id
;
57 Current_Package
: Project_Node_Id
);
58 -- Parse a case construction
60 procedure Parse_Declarative_Items
61 (Declarations
: out Project_Node_Id
;
63 First_Attribute
: Attribute_Node_Id
;
64 Current_Project
: Project_Node_Id
;
65 Current_Package
: Project_Node_Id
);
66 -- Parse declarative items. Depending on In_Zone, some declarative
67 -- items may be forbiden.
69 procedure Parse_Package_Declaration
70 (Package_Declaration
: out Project_Node_Id
;
71 Current_Project
: Project_Node_Id
);
72 -- Parse a package declaration
74 procedure Parse_String_Type_Declaration
75 (String_Type
: out Project_Node_Id
;
76 Current_Project
: Project_Node_Id
);
77 -- type <name> is ( <literal_string> { , <literal_string> } ) ;
79 procedure Parse_Variable_Declaration
80 (Variable
: out Project_Node_Id
;
81 Current_Project
: Project_Node_Id
;
82 Current_Package
: Project_Node_Id
);
83 -- Parse a variable assignment
84 -- <variable_Name> := <expression>; OR
85 -- <variable_Name> : <string_type_Name> := <string_expression>;
92 (Declarations
: out Project_Node_Id
;
93 Current_Project
: Project_Node_Id
;
94 Extends
: Project_Node_Id
)
96 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
99 Declarations
:= Default_Project_Node
(Of_Kind
=> N_Project_Declaration
);
100 Set_Location_Of
(Declarations
, To
=> Token_Ptr
);
101 Set_Extended_Project_Of
(Declarations
, To
=> Extends
);
102 Set_Project_Declaration_Of
(Current_Project
, Declarations
);
103 Parse_Declarative_Items
104 (Declarations
=> First_Declarative_Item
,
105 In_Zone
=> In_Project
,
106 First_Attribute
=> Prj
.Attr
.Attribute_First
,
107 Current_Project
=> Current_Project
,
108 Current_Package
=> Empty_Node
);
109 Set_First_Declarative_Item_Of
110 (Declarations
, To
=> First_Declarative_Item
);
113 ---------------------------------
114 -- Parse_Attribute_Declaration --
115 ---------------------------------
117 procedure Parse_Attribute_Declaration
118 (Attribute
: out Project_Node_Id
;
119 First_Attribute
: Attribute_Node_Id
;
120 Current_Project
: Project_Node_Id
;
121 Current_Package
: Project_Node_Id
)
123 Current_Attribute
: Attribute_Node_Id
:= First_Attribute
;
124 Full_Associative_Array
: Boolean := False;
125 Attribute_Name
: Name_Id
:= No_Name
;
126 Optional_Index
: Boolean := False;
127 Pkg_Id
: Package_Node_Id
:= Empty_Package
;
128 Warning
: Boolean := False;
131 Attribute
:= Default_Project_Node
(Of_Kind
=> N_Attribute_Declaration
);
132 Set_Location_Of
(Attribute
, To
=> Token_Ptr
);
133 Set_Previous_Line_Node
(Attribute
);
139 -- Body may be an attribute name
141 if Token
= Tok_Body
then
142 Token
:= Tok_Identifier
;
143 Token_Name
:= Snames
.Name_Body
;
146 Expect
(Tok_Identifier
, "identifier");
148 if Token
= Tok_Identifier
then
149 Attribute_Name
:= Token_Name
;
150 Set_Name_Of
(Attribute
, To
=> Token_Name
);
151 Set_Location_Of
(Attribute
, To
=> Token_Ptr
);
153 -- Find the attribute
156 Attribute_Node_Id_Of
(Token_Name
, First_Attribute
);
158 -- If the attribute cannot be found, create the attribute if inside
159 -- an unknown package.
161 if Current_Attribute
= Empty_Attribute
then
162 if Current_Package
/= Empty_Node
163 and then Expression_Kind_Of
(Current_Package
) = Ignored
165 Pkg_Id
:= Package_Id_Of
(Current_Package
);
166 Add_Attribute
(Pkg_Id
, Token_Name
, Current_Attribute
);
167 Error_Msg_Name_1
:= Token_Name
;
168 Error_Msg
("?unknown attribute {", Token_Ptr
);
171 -- If not a valid attribute name, issue an error, or a warning
172 -- if inside a package that does not need to be checked.
174 Warning
:= Current_Package
/= Empty_Node
and then
175 Current_Packages_To_Check
/= All_Packages
;
179 -- Check that we are not in a package to check
181 Get_Name_String
(Name_Of
(Current_Package
));
183 for Index
in Current_Packages_To_Check
'Range loop
184 if Name_Buffer
(1 .. Name_Len
) =
185 Current_Packages_To_Check
(Index
).all
193 Error_Msg_Name_1
:= Token_Name
;
196 Error_Msg
("?undefined attribute {", Token_Ptr
);
199 Error_Msg
("undefined attribute {", Token_Ptr
);
203 -- Set, if appropriate the index case insensitivity flag
205 elsif Attribute_Kind_Of
(Current_Attribute
) in
206 Case_Insensitive_Associative_Array
..
207 Optional_Index_Case_Insensitive_Associative_Array
209 Set_Case_Insensitive
(Attribute
, To
=> True);
212 Scan
; -- past the attribute name
215 -- Change obsolete names of attributes to the new names
217 if Current_Package
/= Empty_Node
218 and then Expression_Kind_Of
(Current_Package
) /= Ignored
220 case Name_Of
(Attribute
) is
221 when Snames
.Name_Specification
=>
222 Set_Name_Of
(Attribute
, To
=> Snames
.Name_Spec
);
224 when Snames
.Name_Specification_Suffix
=>
225 Set_Name_Of
(Attribute
, To
=> Snames
.Name_Spec_Suffix
);
227 when Snames
.Name_Implementation
=>
228 Set_Name_Of
(Attribute
, To
=> Snames
.Name_Body
);
230 when Snames
.Name_Implementation_Suffix
=>
231 Set_Name_Of
(Attribute
, To
=> Snames
.Name_Body_Suffix
);
238 -- Associative array attributes
240 if Token
= Tok_Left_Paren
then
242 -- If the attribute is not an associative array attribute, report
243 -- an error. If this information is still unknown, set the kind
244 -- to Associative_Array.
246 if Current_Attribute
/= Empty_Attribute
247 and then Attribute_Kind_Of
(Current_Attribute
) = Single
249 Error_Msg
("the attribute """ &
251 (Attribute_Name_Of
(Current_Attribute
)) &
252 """ cannot be an associative array",
253 Location_Of
(Attribute
));
255 elsif Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
256 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Associative_Array
);
259 Scan
; -- past the left parenthesis
260 Expect
(Tok_String_Literal
, "literal string");
262 if Token
= Tok_String_Literal
then
263 Set_Associative_Array_Index_Of
(Attribute
, Token_Name
);
264 Scan
; -- past the literal string index
266 if Token
= Tok_At
then
267 case Attribute_Kind_Of
(Current_Attribute
) is
268 when Optional_Index_Associative_Array |
269 Optional_Index_Case_Insensitive_Associative_Array
=>
271 Expect
(Tok_Integer_Literal
, "integer literal");
273 if Token
= Tok_Integer_Literal
then
275 -- Set the source index value from given literal
278 Index
: constant Int
:=
279 UI_To_Int
(Int_Literal_Value
);
282 Error_Msg
("index cannot be zero", Token_Ptr
);
284 Set_Source_Index_Of
(Attribute
, To
=> Index
);
292 Error_Msg
("index not allowed here", Token_Ptr
);
295 if Token
= Tok_Integer_Literal
then
302 Expect
(Tok_Right_Paren
, "`)`");
304 if Token
= Tok_Right_Paren
then
305 Scan
; -- past the right parenthesis
309 -- If it is an associative array attribute and there are no left
310 -- parenthesis, then this is a full associative array declaration.
311 -- Flag it as such for later processing of its value.
313 if Current_Attribute
/= Empty_Attribute
315 Attribute_Kind_Of
(Current_Attribute
) /= Single
317 if Attribute_Kind_Of
(Current_Attribute
) = Unknown
then
318 Set_Attribute_Kind_Of
(Current_Attribute
, To
=> Single
);
321 Full_Associative_Array
:= True;
326 -- Set the expression kind of the attribute
328 if Current_Attribute
/= Empty_Attribute
then
329 Set_Expression_Kind_Of
330 (Attribute
, To
=> Variable_Kind_Of
(Current_Attribute
));
331 Optional_Index
:= Optional_Index_Of
(Current_Attribute
);
334 Expect
(Tok_Use
, "USE");
336 if Token
= Tok_Use
then
339 if Full_Associative_Array
then
341 -- Expect <project>'<same_attribute_name>, or
342 -- <project>.<same_package_name>'<same_attribute_name>
345 The_Project
: Project_Node_Id
:= Empty_Node
;
346 -- The node of the project where the associative array is
349 The_Package
: Project_Node_Id
:= Empty_Node
;
350 -- The node of the package where the associative array is
353 Project_Name
: Name_Id
:= No_Name
;
354 -- The name of the project where the associative array is
357 Location
: Source_Ptr
:= No_Location
;
358 -- The location of the project name
361 Expect
(Tok_Identifier
, "identifier");
363 if Token
= Tok_Identifier
then
364 Location
:= Token_Ptr
;
366 -- Find the project node in the imported project or
367 -- in the project being extended.
369 The_Project
:= Imported_Or_Extended_Project_Of
370 (Current_Project
, Token_Name
);
372 if The_Project
= Empty_Node
then
373 Error_Msg
("unknown project", Location
);
374 Scan
; -- past the project name
377 Project_Name
:= Token_Name
;
378 Scan
; -- past the project name
380 -- If this is inside a package, a dot followed by the
381 -- name of the package must followed the project name.
383 if Current_Package
/= Empty_Node
then
384 Expect
(Tok_Dot
, "`.`");
386 if Token
/= Tok_Dot
then
387 The_Project
:= Empty_Node
;
390 Scan
; -- past the dot
391 Expect
(Tok_Identifier
, "identifier");
393 if Token
/= Tok_Identifier
then
394 The_Project
:= Empty_Node
;
396 -- If it is not the same package name, issue error
398 elsif Token_Name
/= Name_Of
(Current_Package
) then
399 The_Project
:= Empty_Node
;
401 ("not the same package as " &
402 Get_Name_String
(Name_Of
(Current_Package
)),
406 The_Package
:= First_Package_Of
(The_Project
);
408 -- Look for the package node
410 while The_Package
/= Empty_Node
411 and then Name_Of
(The_Package
) /= Token_Name
414 Next_Package_In_Project
(The_Package
);
417 -- If the package cannot be found in the
418 -- project, issue an error.
420 if The_Package
= Empty_Node
then
421 The_Project
:= Empty_Node
;
422 Error_Msg_Name_2
:= Project_Name
;
423 Error_Msg_Name_1
:= Token_Name
;
425 ("package % not declared in project %",
429 Scan
; -- past the package name
436 if The_Project
/= Empty_Node
then
438 -- Looking for '<same attribute name>
440 Expect
(Tok_Apostrophe
, "`''`");
442 if Token
/= Tok_Apostrophe
then
443 The_Project
:= Empty_Node
;
446 Scan
; -- past the apostrophe
447 Expect
(Tok_Identifier
, "identifier");
449 if Token
/= Tok_Identifier
then
450 The_Project
:= Empty_Node
;
453 -- If it is not the same attribute name, issue error
455 if Token_Name
/= Attribute_Name
then
456 The_Project
:= Empty_Node
;
457 Error_Msg_Name_1
:= Attribute_Name
;
458 Error_Msg
("invalid name, should be %", Token_Ptr
);
461 Scan
; -- past the attribute name
466 if The_Project
= Empty_Node
then
468 -- If there were any problem, set the attribute id to null,
469 -- so that the node will not be recorded.
471 Current_Attribute
:= Empty_Attribute
;
474 -- Set the appropriate field in the node.
475 -- Note that the index and the expression are nil. This
476 -- characterizes full associative array attribute
479 Set_Associative_Project_Of
(Attribute
, The_Project
);
480 Set_Associative_Package_Of
(Attribute
, The_Package
);
484 -- Other attribute declarations (not full associative array)
488 Expression_Location
: constant Source_Ptr
:= Token_Ptr
;
489 -- The location of the first token of the expression
491 Expression
: Project_Node_Id
:= Empty_Node
;
492 -- The expression, value for the attribute declaration
495 -- Get the expression value and set it in the attribute node
498 (Expression
=> Expression
,
499 Current_Project
=> Current_Project
,
500 Current_Package
=> Current_Package
,
501 Optional_Index
=> Optional_Index
);
502 Set_Expression_Of
(Attribute
, To
=> Expression
);
504 -- If the expression is legal, but not of the right kind
505 -- for the attribute, issue an error.
507 if Current_Attribute
/= Empty_Attribute
508 and then Expression
/= Empty_Node
509 and then Variable_Kind_Of
(Current_Attribute
) /=
510 Expression_Kind_Of
(Expression
)
512 if Variable_Kind_Of
(Current_Attribute
) = Undefined
then
515 To
=> Expression_Kind_Of
(Expression
));
519 ("wrong expression kind for attribute """ &
521 (Attribute_Name_Of
(Current_Attribute
)) &
523 Expression_Location
);
530 -- If the attribute was not recognized, return an empty node.
531 -- It may be that it is not in a package to check, and the node will
532 -- not be added to the tree.
534 if Current_Attribute
= Empty_Attribute
then
535 Attribute
:= Empty_Node
;
538 Set_End_Of_Line
(Attribute
);
539 Set_Previous_Line_Node
(Attribute
);
540 end Parse_Attribute_Declaration
;
542 -----------------------------
543 -- Parse_Case_Construction --
544 -----------------------------
546 procedure Parse_Case_Construction
547 (Case_Construction
: out Project_Node_Id
;
548 First_Attribute
: Attribute_Node_Id
;
549 Current_Project
: Project_Node_Id
;
550 Current_Package
: Project_Node_Id
)
552 Current_Item
: Project_Node_Id
:= Empty_Node
;
553 Next_Item
: Project_Node_Id
:= Empty_Node
;
554 First_Case_Item
: Boolean := True;
556 Variable_Location
: Source_Ptr
:= No_Location
;
558 String_Type
: Project_Node_Id
:= Empty_Node
;
560 Case_Variable
: Project_Node_Id
:= Empty_Node
;
562 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
564 First_Choice
: Project_Node_Id
:= Empty_Node
;
566 When_Others
: Boolean := False;
567 -- Set to True when there is a "when others =>" clause
571 Default_Project_Node
(Of_Kind
=> N_Case_Construction
);
572 Set_Location_Of
(Case_Construction
, To
=> Token_Ptr
);
578 -- Get the switch variable
580 Expect
(Tok_Identifier
, "identifier");
582 if Token
= Tok_Identifier
then
583 Variable_Location
:= Token_Ptr
;
584 Parse_Variable_Reference
585 (Variable
=> Case_Variable
,
586 Current_Project
=> Current_Project
,
587 Current_Package
=> Current_Package
);
588 Set_Case_Variable_Reference_Of
589 (Case_Construction
, To
=> Case_Variable
);
592 if Token
/= Tok_Is
then
597 if Case_Variable
/= Empty_Node
then
598 String_Type
:= String_Type_Of
(Case_Variable
);
600 if String_Type
= Empty_Node
then
601 Error_Msg
("variable """ &
602 Get_Name_String
(Name_Of
(Case_Variable
)) &
608 Expect
(Tok_Is
, "IS");
610 if Token
= Tok_Is
then
611 Set_End_Of_Line
(Case_Construction
);
612 Set_Previous_Line_Node
(Case_Construction
);
613 Set_Next_End_Node
(Case_Construction
);
620 Start_New_Case_Construction
(String_Type
);
624 while Token
= Tok_When
loop
626 if First_Case_Item
then
627 Current_Item
:= Default_Project_Node
(Of_Kind
=> N_Case_Item
);
628 Set_First_Case_Item_Of
(Case_Construction
, To
=> Current_Item
);
629 First_Case_Item
:= False;
632 Next_Item
:= Default_Project_Node
(Of_Kind
=> N_Case_Item
);
633 Set_Next_Case_Item
(Current_Item
, To
=> Next_Item
);
634 Current_Item
:= Next_Item
;
637 Set_Location_Of
(Current_Item
, To
=> Token_Ptr
);
643 if Token
= Tok_Others
then
646 -- Scan past "others"
650 Expect
(Tok_Arrow
, "`=>`");
651 Set_End_Of_Line
(Current_Item
);
652 Set_Previous_Line_Node
(Current_Item
);
654 -- Empty_Node in Field1 of a Case_Item indicates
655 -- the "when others =>" branch.
657 Set_First_Choice_Of
(Current_Item
, To
=> Empty_Node
);
659 Parse_Declarative_Items
660 (Declarations
=> First_Declarative_Item
,
661 In_Zone
=> In_Case_Construction
,
662 First_Attribute
=> First_Attribute
,
663 Current_Project
=> Current_Project
,
664 Current_Package
=> Current_Package
);
666 -- "when others =>" must be the last branch, so save the
667 -- Case_Item and exit
669 Set_First_Declarative_Item_Of
670 (Current_Item
, To
=> First_Declarative_Item
);
674 Parse_Choice_List
(First_Choice
=> First_Choice
);
675 Set_First_Choice_Of
(Current_Item
, To
=> First_Choice
);
677 Expect
(Tok_Arrow
, "`=>`");
678 Set_End_Of_Line
(Current_Item
);
679 Set_Previous_Line_Node
(Current_Item
);
681 Parse_Declarative_Items
682 (Declarations
=> First_Declarative_Item
,
683 In_Zone
=> In_Case_Construction
,
684 First_Attribute
=> First_Attribute
,
685 Current_Project
=> Current_Project
,
686 Current_Package
=> Current_Package
);
688 Set_First_Declarative_Item_Of
689 (Current_Item
, To
=> First_Declarative_Item
);
694 End_Case_Construction
695 (Check_All_Labels
=> not When_Others
and not Quiet_Output
,
696 Case_Location
=> Location_Of
(Case_Construction
));
698 Expect
(Tok_End
, "`END CASE`");
699 Remove_Next_End_Node
;
701 if Token
= Tok_End
then
707 Expect
(Tok_Case
, "CASE");
715 Expect
(Tok_Semicolon
, "`;`");
716 Set_Previous_End_Node
(Case_Construction
);
718 end Parse_Case_Construction
;
720 -----------------------------
721 -- Parse_Declarative_Items --
722 -----------------------------
724 procedure Parse_Declarative_Items
725 (Declarations
: out Project_Node_Id
;
727 First_Attribute
: Attribute_Node_Id
;
728 Current_Project
: Project_Node_Id
;
729 Current_Package
: Project_Node_Id
)
731 Current_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
732 Next_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
733 Current_Declaration
: Project_Node_Id
:= Empty_Node
;
734 Item_Location
: Source_Ptr
:= No_Location
;
737 Declarations
:= Empty_Node
;
740 -- We are always positioned at the token that precedes
741 -- the first token of the declarative element.
746 Item_Location
:= Token_Ptr
;
749 when Tok_Identifier
=>
751 if In_Zone
= In_Case_Construction
then
752 Error_Msg
("a variable cannot be declared here",
756 Parse_Variable_Declaration
757 (Current_Declaration
,
758 Current_Project
=> Current_Project
,
759 Current_Package
=> Current_Package
);
761 Set_End_Of_Line
(Current_Declaration
);
762 Set_Previous_Line_Node
(Current_Declaration
);
766 Parse_Attribute_Declaration
767 (Attribute
=> Current_Declaration
,
768 First_Attribute
=> First_Attribute
,
769 Current_Project
=> Current_Project
,
770 Current_Package
=> Current_Package
);
772 Set_End_Of_Line
(Current_Declaration
);
773 Set_Previous_Line_Node
(Current_Declaration
);
781 -- Package declaration
783 if In_Zone
/= In_Project
then
784 Error_Msg
("a package cannot be declared here", Token_Ptr
);
787 Parse_Package_Declaration
788 (Package_Declaration
=> Current_Declaration
,
789 Current_Project
=> Current_Project
);
791 Set_Previous_End_Node
(Current_Declaration
);
795 -- Type String Declaration
797 if In_Zone
/= In_Project
then
798 Error_Msg
("a string type cannot be declared here",
802 Parse_String_Type_Declaration
803 (String_Type
=> Current_Declaration
,
804 Current_Project
=> Current_Project
);
806 Set_End_Of_Line
(Current_Declaration
);
807 Set_Previous_Line_Node
(Current_Declaration
);
813 Parse_Case_Construction
814 (Case_Construction
=> Current_Declaration
,
815 First_Attribute
=> First_Attribute
,
816 Current_Project
=> Current_Project
,
817 Current_Package
=> Current_Package
);
819 Set_Previous_End_Node
(Current_Declaration
);
824 -- We are leaving Parse_Declarative_Items positionned
825 -- at the first token after the list of declarative items.
826 -- It could be "end" (for a project, a package declaration or
827 -- a case construction) or "when" (for a case construction)
831 Expect
(Tok_Semicolon
, "`;` after declarative items");
833 -- Insert an N_Declarative_Item in the tree, but only if
834 -- Current_Declaration is not an empty node.
836 if Current_Declaration
/= Empty_Node
then
837 if Current_Declarative_Item
= Empty_Node
then
838 Current_Declarative_Item
:=
839 Default_Project_Node
(Of_Kind
=> N_Declarative_Item
);
840 Declarations
:= Current_Declarative_Item
;
843 Next_Declarative_Item
:=
844 Default_Project_Node
(Of_Kind
=> N_Declarative_Item
);
845 Set_Next_Declarative_Item
846 (Current_Declarative_Item
, To
=> Next_Declarative_Item
);
847 Current_Declarative_Item
:= Next_Declarative_Item
;
850 Set_Current_Item_Node
851 (Current_Declarative_Item
, To
=> Current_Declaration
);
852 Set_Location_Of
(Current_Declarative_Item
, To
=> Item_Location
);
857 end Parse_Declarative_Items
;
859 -------------------------------
860 -- Parse_Package_Declaration --
861 -------------------------------
863 procedure Parse_Package_Declaration
864 (Package_Declaration
: out Project_Node_Id
;
865 Current_Project
: Project_Node_Id
)
867 First_Attribute
: Attribute_Node_Id
:= Empty_Attribute
;
868 Current_Package
: Package_Node_Id
:= Empty_Package
;
869 First_Declarative_Item
: Project_Node_Id
:= Empty_Node
;
872 Package_Declaration
:=
873 Default_Project_Node
(Of_Kind
=> N_Package_Declaration
);
874 Set_Location_Of
(Package_Declaration
, To
=> Token_Ptr
);
876 -- 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
;