-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc --
+-- Copyright (C) 2001-2004 Free Software Foundation, Inc --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
with Snames;
with Types; use Types;
with Prj.Attr; use Prj.Attr;
+with Uintp; use Uintp;
package body Prj.Dect is
Current_Attribute : Attribute_Node_Id := First_Attribute;
Full_Associative_Array : Boolean := False;
Attribute_Name : Name_Id := No_Name;
+ Optional_Index : Boolean := False;
begin
Attribute := Default_Project_Node (Of_Kind => N_Attribute_Declaration);
Set_Location_Of (Attribute, To => Token_Ptr);
+ Set_Previous_Line_Node (Attribute);
-- Scan past "for"
-- Set, if appropriate the index case insensitivity flag
- elsif Attributes.Table (Current_Attribute).Kind_2 =
- Case_Insensitive_Associative_Array
+ elsif Attributes.Table (Current_Attribute).Kind_2 in
+ Case_Insensitive_Associative_Array ..
+ Optional_Index_Case_Insensitive_Associative_Array
then
Set_Case_Insensitive (Attribute, To => True);
end if;
if Token = Tok_String_Literal then
Set_Associative_Array_Index_Of (Attribute, Token_Name);
Scan; -- past the literal string index
+
+ if Token = Tok_At then
+ case Attributes.Table (Current_Attribute).Kind_2 is
+ when Optional_Index_Associative_Array |
+ Optional_Index_Case_Insensitive_Associative_Array =>
+ Scan;
+ Expect (Tok_Integer_Literal, "integer literal");
+
+ if Token = Tok_Integer_Literal then
+
+ -- Set the source index value from given literal
+
+ declare
+ Index : constant Int :=
+ UI_To_Int (Int_Literal_Value);
+ begin
+ if Index = 0 then
+ Error_Msg ("index cannot be zero", Token_Ptr);
+ else
+ Set_Source_Index_Of (Attribute, To => Index);
+ end if;
+ end;
+
+ Scan;
+ end if;
+
+ when others =>
+ Error_Msg ("index not allowed here", Token_Ptr);
+ Scan;
+
+ if Token = Tok_Integer_Literal then
+ Scan;
+ end if;
+ end case;
+ end if;
end if;
Expect (Tok_Right_Paren, "`)`");
if Current_Attribute /= Empty_Attribute then
Set_Expression_Kind_Of
(Attribute, To => Attributes.Table (Current_Attribute).Kind_1);
+ Optional_Index := Attributes.Table (Current_Attribute).Optional_Index;
end if;
Expect (Tok_Use, "USE");
Parse_Expression
(Expression => Expression,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => Optional_Index);
Set_Expression_Of (Attribute, To => Expression);
-- If the expression is legal, but not of the right kind
if Current_Attribute = Empty_Attribute then
Attribute := Empty_Node;
end if;
+
+ Set_End_Of_Line (Attribute);
+ Set_Previous_Line_Node (Attribute);
end Parse_Attribute_Declaration;
-----------------------------
Expect (Tok_Is, "IS");
if Token = Tok_Is then
+ Set_End_Of_Line (Case_Construction);
+ Set_Previous_Line_Node (Case_Construction);
+ Set_Next_End_Node (Case_Construction);
-- Scan past "is"
Scan;
Expect (Tok_Arrow, "`=>`");
+ Set_End_Of_Line (Current_Item);
+ Set_Previous_Line_Node (Current_Item);
-- Empty_Node in Field1 of a Case_Item indicates
-- the "when others =>" branch.
Set_First_Choice_Of (Current_Item, To => First_Choice);
Expect (Tok_Arrow, "`=>`");
+ Set_End_Of_Line (Current_Item);
+ Set_Previous_Line_Node (Current_Item);
Parse_Declarative_Items
(Declarations => First_Declarative_Item,
End_Case_Construction;
Expect (Tok_End, "`END CASE`");
+ Remove_Next_End_Node;
if Token = Tok_End then
Scan;
Expect (Tok_Semicolon, "`;`");
+ Set_Previous_End_Node (Case_Construction);
end Parse_Case_Construction;
Current_Project => Current_Project,
Current_Package => Current_Package);
+ Set_End_Of_Line (Current_Declaration);
+ Set_Previous_Line_Node (Current_Declaration);
+
when Tok_For =>
Parse_Attribute_Declaration
Current_Project => Current_Project,
Current_Package => Current_Package);
+ Set_End_Of_Line (Current_Declaration);
+ Set_Previous_Line_Node (Current_Declaration);
+
when Tok_Package =>
-- Package declaration
(Package_Declaration => Current_Declaration,
Current_Project => Current_Project);
+ Set_Previous_End_Node (Current_Declaration);
+
when Tok_Type =>
-- Type String Declaration
(String_Type => Current_Declaration,
Current_Project => Current_Project);
+ Set_End_Of_Line (Current_Declaration);
+ Set_Previous_Line_Node (Current_Declaration);
+
when Tok_Case =>
-- Case construction
Current_Project => Current_Project,
Current_Package => Current_Package);
+ Set_Previous_End_Node (Current_Declaration);
+
when others =>
exit;
end if;
Expect (Tok_Semicolon, "`;`");
+ Set_End_Of_Line (Package_Declaration);
+ Set_Previous_Line_Node (Package_Declaration);
elsif Token = Tok_Is then
+ Set_End_Of_Line (Package_Declaration);
+ Set_Previous_Line_Node (Package_Declaration);
+ Set_Next_End_Node (Package_Declaration);
Parse_Declarative_Items
(Declarations => First_Declarative_Item,
end if;
Expect (Tok_Semicolon, "`;`");
+ Remove_Next_End_Node;
else
Error_Msg ("expected IS or RENAMES", Token_Ptr);
Parse_Expression
(Expression => Expression,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => False);
Set_Expression_Of (Variable, To => Expression);
if Expression /= Empty_Node then