+2019-12-16 Bob Duff <duff@adacore.com>
+
+ * par.adb: Add Scopes function to do range checking on the scope
+ stack. Call Scopes all over the parser. Add
+ SIS_Aspect_Import_Seen flag.
+ * par-ch6.adb (P_Subprogram): Initialize SIS_Aspect_Import_Seen
+ to False at the start, and check it at the end.
+ * par-ch13.adb (Get_Aspect_Specifications): Set
+ SIS_Aspect_Import_Seen to True when appropriate.
+ * par-ch10.adb, par-ch12.adb, par-ch2.adb, par-ch3.adb,
+ par-ch5.adb, par-ch7.adb, par-ch9.adb, par-endh.adb,
+ par-util.adb: Call Scopes.
+
2019-12-16 Eric Botcazou <ebotcazou@adacore.com>
* sem_prag.adb (Atomic_Components): Remove local variable and
or else Token in Token_Class_Deckn
then
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Sloc := SIS_Sloc;
- Scope.Table (Scope.Last).Ecol := SIS_Ecol;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Sloc := SIS_Sloc;
+ Scopes (Scope.Last).Ecol := SIS_Ecol;
+ Scopes (Scope.Last).Lreq := False;
SIS_Entry_Active := False;
-- If we had a missing semicolon in the declaration, then
elsif Token /= Tok_Left_Paren
and then Token_Is_At_Start_Of_Line
- and then Start_Column <= Scope.Table (Scope.Last).Ecol
+ and then Start_Column <= Scopes (Scope.Last).Ecol
then
return No_List;
Inside_Depends := True;
end if;
- -- Parse the aspect definition depening on the expected
+ -- Note that we have seen an Import aspect specification.
+ -- This matters only while parsing a subprogram.
+
+ if A_Id = Aspect_Import then
+ SIS_Aspect_Import_Seen := True;
+ -- Should do it only for subprograms
+ end if;
+
+ -- Parse the aspect definition depending on the expected
-- argument kind.
if Aspect_Argument (A_Id) = Name
Set_Identifier (Rep_Clause_Node, Identifier_Node);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Record;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Record;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Scan; -- past RECORD
Record_Items := P_Pragmas_Opt;
-- Local variables
- Interface_Check_Required : Boolean := False;
- -- Set True if check of pragma INTERFACE is required
-
Import_Check_Required : Boolean := False;
- -- Set True if check of pragma IMPORT is required
+ -- Set True if check of pragma IMPORT or INTERFACE is required
Arg_Count : Nat := 0;
-- Number of argument associations processed
-- See if special INTERFACE/IMPORT check is required
if SIS_Entry_Active then
- Interface_Check_Required := (Prag_Name = Name_Interface);
- Import_Check_Required := (Prag_Name = Name_Import);
+ Import_Check_Required :=
+ (Prag_Name = Name_Import) or else (Prag_Name = Name_Interface);
else
- Interface_Check_Required := False;
- Import_Check_Required := False;
+ Import_Check_Required := False;
end if;
-- Set global to indicate if we are within a Depends pragma
Nam_In (Prag_Name, Name_Restriction_Warnings,
Name_Restrictions));
- if Arg_Count = 2
- and then (Interface_Check_Required or else Import_Check_Required)
- then
+ if Arg_Count = 2 and then Import_Check_Required then
-- Here is where we cancel the SIS active status if this pragma
-- supplies a body for the currently active subprogram spec.
else
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Record;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Labl := Error;
- Scope.Table (Scope.Last).Junk := (Token /= Tok_Record);
+ Scopes (Scope.Last).Etyp := E_Record;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Junk := (Token /= Tok_Record);
T_Record;
-- additional clue that confirms the incorrect spelling.
if Token /= Tok_Identifier then
- if Start_Column > Scope.Table (Scope.Last).Ecol
+ if Start_Column > Scopes (Scope.Last).Ecol
and then Is_Reserved_Identifier
then
Save_Scan_State (Scan_State); -- at reserved id
begin
Variant_Part_Node := New_Node (N_Variant_Part, Token_Ptr);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Case;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Etyp := E_Case;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Ecol := Start_Column;
Scan; -- past CASE
Case_Node := P_Expression;
-- scan it out
Push_Scope_Stack;
- Scope.Table (Scope.Last).Sloc := SIS_Sloc;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Ecol := SIS_Ecol;
- Scope.Table (Scope.Last).Labl := SIS_Labl;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Sloc := SIS_Sloc;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Ecol := SIS_Ecol;
+ Scopes (Scope.Last).Labl := SIS_Labl;
+ Scopes (Scope.Last).Lreq := False;
SIS_Entry_Active := False;
Scan; -- past BEGIN
Set_Handled_Statement_Sequence (Body_Node,
-- of the expected column of the end for this sequence
if SS_Flags.Eftm
- or else Start_Column < Scope.Table (Scope.Last).Ecol
+ or else Start_Column < Scopes (Scope.Last).Ecol
then
Test_Statement_Required;
exit;
-- of the expected column of the end for this sequence
if SS_Flags.Eltm
- or else Start_Column < Scope.Table (Scope.Last).Ecol
+ or else Start_Column < Scopes (Scope.Last).Ecol
then
Test_Statement_Required;
exit;
-- is not permitted.
if not SS_Flags.Extm and then
- Start_Column >= Scope.Table (Scope.Last).Ecol
+ Start_Column >= Scopes (Scope.Last).Ecol
then
Error_Msg_SC ("exception handler not permitted here");
-- expected column of the end for this sequence.
if SS_Flags.Ortm
- or else Start_Column < Scope.Table (Scope.Last).Ecol
+ or else Start_Column < Scopes (Scope.Last).Ecol
then
Test_Statement_Required;
exit;
-- the expected column of the end for this sequence.
if SS_Flags.Whtm
- or else Start_Column < Scope.Table (Scope.Last).Ecol
+ or else Start_Column < Scopes (Scope.Last).Ecol
then
Test_Statement_Required;
exit;
procedure Check_If_Column is
begin
if RM_Column_Check and then Token_Is_At_Start_Of_Line
- and then Start_Column /= Scope.Table (Scope.Last).Ecol
+ and then Start_Column /= Scopes (Scope.Last).Ecol
then
- Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
+ Error_Msg_Col := Scopes (Scope.Last).Ecol;
Error_Msg_SC ("(style) this token should be@");
end if;
end Check_If_Column;
If_Node := New_Node (N_If_Statement, Token_Ptr);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_If;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Labl := Error;
- Scope.Table (Scope.Last).Node := If_Node;
+ Scopes (Scope.Last).Etyp := E_If;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Node := If_Node;
if Token = Tok_If then
Loc := Token_Ptr;
Case_Node := New_Node (N_Case_Statement, Token_Ptr);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Case;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Labl := Error;
- Scope.Table (Scope.Last).Node := Case_Node;
+ Scopes (Scope.Last).Etyp := E_Case;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Node := Case_Node;
Scan; -- past CASE
Set_Expression (Case_Node, P_Expression_No_Right_Paren);
-- complain about the missing WHEN, and discard the junk statements.
elsif not Token_Is_At_Start_Of_Line
- or else Start_Column > Scope.Table (Scope.Last).Ecol
+ or else Start_Column > Scopes (Scope.Last).Ecol
then
Error_Msg_BC ("WHEN (case statement alternative) expected");
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Labl := Loop_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Etyp := E_Loop;
+ Scopes (Scope.Last).Labl := Loop_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Loop;
Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
TF_Loop;
Set_Comes_From_Source (Created_Name, False);
Set_Has_Created_Identifier (Loop_Node, True);
Set_Identifier (Loop_Node, Created_Name);
- Scope.Table (Scope.Last).Labl := Created_Name;
+ Scopes (Scope.Last).Labl := Created_Name;
else
Set_Identifier (Loop_Node, Loop_Name);
end if;
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Labl := Loop_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Etyp := E_Loop;
+ Scopes (Scope.Last).Labl := Loop_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Loop;
Loop_For_Flag := (Prev_Token = Tok_Loop);
Scan; -- past FOR
Set_Comes_From_Source (Created_Name, False);
Set_Has_Created_Identifier (Loop_Node, True);
Set_Identifier (Loop_Node, Created_Name);
- Scope.Table (Scope.Last).Labl := Created_Name;
+ Scopes (Scope.Last).Labl := Created_Name;
else
Set_Identifier (Loop_Node, Loop_Name);
end if;
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Labl := Loop_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Etyp := E_Loop;
+ Scopes (Scope.Last).Labl := Loop_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Loop;
Loop_While_Flag := (Prev_Token = Tok_Loop);
Iter_Scheme_Node := New_Node (N_Iteration_Scheme, Token_Ptr);
Set_Comes_From_Source (Created_Name, False);
Set_Has_Created_Identifier (Loop_Node, True);
Set_Identifier (Loop_Node, Created_Name);
- Scope.Table (Scope.Last).Labl := Created_Name;
+ Scopes (Scope.Last).Labl := Created_Name;
else
Set_Identifier (Loop_Node, Loop_Name);
end if;
Block_Node := New_Node (N_Block_Statement, Token_Ptr);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Lreq := Present (Block_Name);
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Labl := Block_Name;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Lreq := Present (Block_Name);
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Labl := Block_Name;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Scan; -- past DECLARE
Set_Comes_From_Source (Created_Name, False);
Set_Has_Created_Identifier (Block_Node, True);
Set_Identifier (Block_Node, Created_Name);
- Scope.Table (Scope.Last).Labl := Created_Name;
+ Scopes (Scope.Last).Labl := Created_Name;
else
Set_Identifier (Block_Node, Block_Name);
end if;
Block_Node := New_Node (N_Block_Statement, Token_Ptr);
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Lreq := Present (Block_Name);
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Labl := Block_Name;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Lreq := Present (Block_Name);
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Labl := Block_Name;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
if No (Block_Name) then
Created_Name :=
Set_Comes_From_Source (Created_Name, False);
Set_Has_Created_Identifier (Block_Node, True);
Set_Identifier (Block_Node, Created_Name);
- Scope.Table (Scope.Last).Labl := Created_Name;
+ Scopes (Scope.Last).Labl := Created_Name;
else
Set_Identifier (Block_Node, Block_Name);
end if;
Append_Elmt (Block_Node, Label_List);
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Scan; -- past BEGIN
Set_Handled_Statement_Sequence
(Block_Node, P_Handled_Sequence_Of_Statements);
if not Token_Is_At_Start_Of_Line then
return False;
- elsif Scope.Table (Scope.Last).Etyp /= E_Case then
+ elsif Scopes (Scope.Last).Etyp /= E_Case then
return False;
else
Check_No_Exit_Name :
for J in reverse 1 .. Scope.Last loop
- if Scope.Table (J).Etyp = E_Loop then
- if Present (Scope.Table (J).Labl)
- and then Comes_From_Source (Scope.Table (J).Labl)
+ if Scopes (J).Etyp = E_Loop then
+ if Present (Scopes (J).Labl)
+ and then Comes_From_Source (Scopes (J).Labl)
then
-- Innermost loop in fact had a name, style check fails
- Style.No_Exit_Name (Scope.Table (J).Labl);
+ Style.No_Exit_Name (Scopes (J).Labl);
end if;
exit Check_No_Exit_Name;
Style.Check_Indentation;
end if;
- Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
+ Error_Msg_Col := Scopes (Scope.Last).Ecol;
if RM_Column_Check
and then Token_Is_At_Start_Of_Line
Error_Msg_SC ("(style) BEGIN in wrong column, should be@");
else
- Scope.Table (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Ecol := Start_Column;
end if;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Scan; -- past BEGIN
Set_Handled_Statement_Sequence (Parent,
P_Handled_Sequence_Of_Statements);
if Parent_Nkind = N_Subprogram_Body
and then Token = Tok_End
- and then Scope.Table (Scope.Last).Etyp = E_Suspicious_Is
+ and then Scopes (Scope.Last).Etyp = E_Suspicious_Is
then
- Scope.Table (Scope.Last).Etyp := E_Bad_Is;
+ Scopes (Scope.Last).Etyp := E_Bad_Is;
-- Otherwise BEGIN is not required for a package body, so we
-- don't mind if it is missing, but we do construct a dummy
-- Prepare to issue error message
- Error_Msg_Sloc := Scope.Table (Scope.Last).Sloc;
- Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
+ Error_Msg_Sloc := Scopes (Scope.Last).Sloc;
+ Error_Msg_Node_1 := Scopes (Scope.Last).Labl;
-- Now issue appropriate message
-- (because it is required to do so under all circumstances). We can
-- therefore reference the entry it removed one past the stack top.
-- What we are interested in is whether it was a case of a bad IS.
+ -- We can't call Scopes here.
if Scope.Table (Scope.Last + 1).Etyp = E_Bad_Is then
Error_Msg -- CODEFIX
-- Set up scope stack entry. Note that the Labl field will be set later
SIS_Entry_Active := False;
+ SIS_Aspect_Import_Seen := False;
SIS_Missing_Semicolon_Message := No_Error_Msg;
Push_Scope_Stack;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Lreq := False;
Aspects := Empty_List;
Name_Node := P_Defining_Program_Unit_Name;
end if;
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
Ignore (Tok_Colon);
-- i.e. that the terminating semicolon should have been IS.
elsif Token = Tok_Begin
- and then Start_Column >= Scope.Table (Scope.Last).Ecol
+ and then Start_Column >= Scopes (Scope.Last).Ecol
then
Error_Msg_SP -- CODEFIX
("|"";"" should be IS!");
Spec_Node : constant Node_Id :=
Parent
- (Scope.Table (Scope.Last).Labl);
+ (Scopes (Scope.Last).Labl);
Lib_Node : Node_Id := Spec_Node;
begin
if Scope.Last > 1 then
Lib_Node :=
- Parent (Scope.Table (Scope.Last - 1).Labl);
+ Parent (Scopes (Scope.Last - 1).Labl);
end if;
if Ada_Version >= Ada_2012
if (Token in Token_Class_Declk
or else
Token = Tok_Identifier)
- and then Start_Column <= Scope.Table (Scope.Last).Ecol
+ and then Start_Column <= Scopes (Scope.Last).Ecol
and then Scope.Last /= 1
then
- Scope.Table (Scope.Last).Etyp := E_Suspicious_Is;
- Scope.Table (Scope.Last).S_Is := Prev_Token_Ptr;
+ Scopes (Scope.Last).Etyp := E_Suspicious_Is;
+ Scopes (Scope.Last).S_Is := Prev_Token_Ptr;
end if;
-- Build and return subprogram body, parsing declarations
and then (Nkind (Specification_Node) /= N_Procedure_Specification
or else not Null_Present (Specification_Node))
then
- SIS_Labl := Scope.Table (Scope.Last).Labl;
- SIS_Sloc := Scope.Table (Scope.Last).Sloc;
- SIS_Ecol := Scope.Table (Scope.Last).Ecol;
+ SIS_Labl := Scopes (Scope.Last).Labl;
+ SIS_Sloc := Scopes (Scope.Last).Sloc;
+ SIS_Ecol := Scopes (Scope.Last).Ecol;
SIS_Declaration_Node := Decl_Node;
SIS_Semicolon_Sloc := Prev_Token_Ptr;
- SIS_Entry_Active := True;
+
+ -- Do not activate the entry if we have "with Import"
+
+ if not SIS_Aspect_Import_Seen then
+ SIS_Entry_Active := True;
+ end if;
end if;
Pop_Scope_Stack;
if Token = Tok_Do then
Push_Scope_Stack;
- Scope.Table (Scope.Last).Ecol := Ret_Strt;
- Scope.Table (Scope.Last).Etyp := E_Return;
- Scope.Table (Scope.Last).Labl := Error;
- Scope.Table (Scope.Last).Sloc := Ret_Sloc;
+ Scopes (Scope.Last).Ecol := Ret_Strt;
+ Scopes (Scope.Last).Etyp := E_Return;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Sloc := Ret_Sloc;
Scan; -- past DO
Set_Handled_Statement_Sequence
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Lreq := False;
Package_Sloc := Token_Ptr;
Scan; -- past PACKAGE
end if;
T_Body;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Name_Node := P_Defining_Program_Unit_Name;
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
if Aspect_Specifications_Present then
-- Cases other than Package_Body
else
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Name_Node := P_Defining_Program_Unit_Name;
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
-- Case of renaming declaration
(Specification_Node, P_Basic_Declarative_Items);
if Token = Tok_Private then
- Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
+ Error_Msg_Col := Scopes (Scope.Last).Ecol;
if RM_Column_Check then
if Token_Is_At_Start_Of_Line
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Lreq := False;
Task_Sloc := Prev_Token_Ptr;
if Token = Tok_Body then
Scan; -- past BODY
Name_Node := P_Defining_Identifier (C_Is);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
if Token = Tok_Left_Paren then
Task_Node := New_Node (N_Task_Type_Declaration, Task_Sloc);
Name_Node := P_Defining_Identifier;
Set_Defining_Identifier (Task_Node, Name_Node);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
Set_Discriminant_Specifications
(Task_Node, P_Known_Discriminant_Part_Opt);
Task_Node := New_Node (N_Single_Task_Declaration, Task_Sloc);
Name_Node := P_Defining_Identifier (C_Is);
Set_Defining_Identifier (Task_Node, Name_Node);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
if Token = Tok_Left_Paren then
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Lreq := False;
Protected_Sloc := Prev_Token_Ptr;
if Token = Tok_Body then
Scan; -- past BODY
Name_Node := P_Defining_Identifier (C_Is);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
if Token = Tok_Left_Paren then
New_Node (N_Protected_Type_Declaration, Protected_Sloc);
Name_Node := P_Defining_Identifier (C_Is);
Set_Defining_Identifier (Protected_Node, Name_Node);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
Set_Discriminant_Specifications
(Protected_Node, P_Known_Discriminant_Part_Opt);
Discard_Junk_List (P_Known_Discriminant_Part_Opt);
end if;
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
end if;
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Ecol := Start_Column;
Accept_Node := New_Node (N_Accept_Statement, Token_Ptr);
Scan; -- past ACCEPT
- Scope.Table (Scope.Last).Labl := Token_Node;
+ Scopes (Scope.Last).Labl := Token_Node;
Current_Node := Token_Node;
Set_Entry_Direct_Name (Accept_Node, P_Identifier (C_Do));
-- Scan out DO if present
if Token = Tok_Do then
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Lreq := False;
Scan; -- past DO
Hand_Seq := P_Handled_Sequence_Of_Statements;
Set_Handled_Statement_Sequence (Accept_Node, Hand_Seq);
Entry_Node := New_Node (N_Entry_Body, Token_Ptr);
Scan; -- past ENTRY
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Lreq := False;
- Scope.Table (Scope.Last).Etyp := E_Name;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Lreq := False;
+ Scopes (Scope.Last).Etyp := E_Name;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
Name_Node := P_Defining_Identifier;
Set_Defining_Identifier (Entry_Node, Name_Node);
- Scope.Table (Scope.Last).Labl := Name_Node;
+ Scopes (Scope.Last).Labl := Name_Node;
Current_Node := Name_Node;
Formal_Part_Node := P_Entry_Body_Formal_Part;
begin
Push_Scope_Stack;
- Scope.Table (Scope.Last).Etyp := E_Select;
- Scope.Table (Scope.Last).Ecol := Start_Column;
- Scope.Table (Scope.Last).Sloc := Token_Ptr;
- Scope.Table (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Etyp := E_Select;
+ Scopes (Scope.Last).Ecol := Start_Column;
+ Scopes (Scope.Last).Sloc := Token_Ptr;
+ Scopes (Scope.Last).Labl := Error;
Select_Sloc := Token_Ptr;
Scan; -- past SELECT
Name_Scan_State : Saved_Scan_State;
-- Save state at start of name if Name_On_Separate_Line is TRUE
- Span_Node : constant Node_Id := Scope.Table (Scope.Last).Node;
+ Span_Node : constant Node_Id := Scopes (Scope.Last).Node;
begin
End_Labl_Present := False;
if Name_On_Separate_Line then
if Token /= Tok_Semicolon or else
- not Same_Label (End_Labl, Scope.Table (Scope.Last).Labl)
+ not Same_Label (End_Labl, Scopes (Scope.Last).Labl)
then
Restore_Scan_State (Name_Scan_State);
End_Labl := Empty;
-- to the scan location past the END token.
else
- End_Labl := Scope.Table (Scope.Last).Labl;
+ End_Labl := Scopes (Scope.Last).Labl;
if End_Labl > Empty_Or_Error then
if Style_Check
and then End_Type = E_Name
and then Explicit_Start_Label (Scope.Last)
- and then Nkind (Parent (Scope.Table (Scope.Last).Labl))
+ and then Nkind (Parent (Scopes (Scope.Last).Labl))
/= N_Block_Statement
then
- Style.No_End_Name (Scope.Table (Scope.Last).Labl);
+ Style.No_End_Name (Scopes (Scope.Last).Labl);
end if;
end if;
end if;
------------------------
procedure Evaluate_End_Entry (SS_Index : Nat) is
- STE : Scope_Table_Entry renames Scope.Table (SS_Index);
+ STE : Scope_Table_Entry renames Scopes (SS_Index).all;
begin
Column_OK := (End_Column = STE.Ecol);
if not Label_OK
and then End_Labl_Present
- and then not Comes_From_Source (Scope.Table (SS_Index).Labl)
+ and then not Comes_From_Source (Scopes (SS_Index).Labl)
then
-- Here is where we will search the suspicious labels table
-- If probably misspelling, then complain, and pretend it is OK
declare
- Nam : constant Node_Or_Entity_Id := Scope.Table (SS_Index).Labl;
+ Nam : constant Node_Or_Entity_Id := Scopes (SS_Index).Labl;
begin
if Nkind (End_Labl) in N_Has_Chars
elsif End_Type = E_Name then
Syntax_OK := (not Explicit_Start_Label (SS_Index))
or else
- (not Scope.Table (SS_Index).Lreq);
+ (not Scopes (SS_Index).Lreq);
-- Otherwise we have cases which don't allow labels anyway, so we
-- certainly accept an END which does not have a label.
--------------------------
function Explicit_Start_Label (SS_Index : Nat) return Boolean is
- L : constant Node_Id := Scope.Table (SS_Index).Labl;
- Etyp : constant SS_End_Type := Scope.Table (SS_Index).Etyp;
+ L : constant Node_Id := Scopes (SS_Index).Labl;
+ Etyp : constant SS_End_Type := Scopes (SS_Index).Etyp;
begin
if No (L) then
-- Suppress message if this was a potentially junk entry (e.g. a record
-- entry where no record keyword was present).
- if Scope.Table (Scope.Last).Junk then
+ if Scopes (Scope.Last).Junk then
return;
end if;
- End_Type := Scope.Table (Scope.Last).Etyp;
- Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
- Error_Msg_Sloc := Scope.Table (Scope.Last).Sloc;
+ End_Type := Scopes (Scope.Last).Etyp;
+ Error_Msg_Col := Scopes (Scope.Last).Ecol;
+ Error_Msg_Sloc := Scopes (Scope.Last).Sloc;
if Explicit_Start_Label (Scope.Last) then
- Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
+ Error_Msg_Node_1 := Scopes (Scope.Last).Labl;
else
Error_Msg_Node_1 := Empty;
end if;
-- missing IS confirms the suspicion.
else -- End_Type = E_Suspicious_Is or E_Bad_Is
- Scope.Table (Scope.Last).Etyp := E_Bad_Is;
+ Scopes (Scope.Last).Etyp := E_Bad_Is;
end if;
end Output_End_Expected;
-- Suppress message if this was a potentially junk entry (e.g. a record
-- entry where no record keyword was present).
- if Scope.Table (Scope.Last).Junk then
+ if Scopes (Scope.Last).Junk then
return;
end if;
- End_Type := Scope.Table (Scope.Last).Etyp;
- Error_Msg_Sloc := Scope.Table (Scope.Last).Sloc;
+ End_Type := Scopes (Scope.Last).Etyp;
+ Error_Msg_Sloc := Scopes (Scope.Last).Sloc;
if Explicit_Start_Label (Scope.Last) then
- Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
+ Error_Msg_Node_1 := Scopes (Scope.Last).Labl;
else
Error_Msg_Node_1 := Empty;
end if;
end if;
else -- End_Type = E_Suspicious_Is or E_Bad_Is
- Scope.Table (Scope.Last).Etyp := E_Bad_Is;
+ Scopes (Scope.Last).Etyp := E_Bad_Is;
end if;
end Output_End_Missing;
Token = Tok_Separate)
and then End_Type >= E_Name
and then (not End_Labl_Present
- or else Same_Label (End_Labl, Scope.Table (1).Labl))
+ or else Same_Label (End_Labl, Scopes (1).Labl))
and then Scope.Last > 1
then
Restore_Scan_State (Scan_State); -- to END
-- line as the opener.
if RM_Column_Check then
- if End_Column /= Scope.Table (Scope.Last).Ecol
- and then Current_Line_Start > Scope.Table (Scope.Last).Sloc
+ if End_Column /= Scopes (Scope.Last).Ecol
+ and then Current_Line_Start > Scopes (Scope.Last).Sloc
-- A special case, for END RECORD, we are also allowed to
-- line up with the TYPE keyword opening the declaration.
- and then (Scope.Table (Scope.Last).Etyp /= E_Record
+ and then (Scopes (Scope.Last).Etyp /= E_Record
or else Get_Column_Number (End_Sloc) /=
Get_Column_Number (Type_Token_Location))
then
- Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
+ Error_Msg_Col := Scopes (Scope.Last).Ecol;
Error_Msg
("(style) END in wrong column, should be@", End_Sloc);
end if;
or else
(not Same_Label
(End_Labl,
- Scope.Table (Scope.Last - 1).Labl)))
+ Scopes (Scope.Last - 1).Labl)))
then
T_Semicolon;
Error_Msg ("duplicate end line ignored", End_Loc);
-- also it is unlikely that such nesting could occur by accident.
Pretty_Good := (Token_OK and (Column_OK or Label_OK))
- or else Scope.Table (Scope.Last).Etyp = E_Record;
+ or else Scopes (Scope.Last).Etyp = E_Record;
-- Next check, if there is a deeper entry in the stack which
-- has a very high probability of being acceptable, then insert
-- practices vary substantially in practice.
if Pretty_Good
- or else End_Column <= Scope.Table (Scope.Last).Ecol
- or else (End_Type = Scope.Table (Scope.Last).Etyp
+ or else End_Column <= Scopes (Scope.Last).Ecol
+ or else (End_Type = Scopes (Scope.Last).Etyp
and then End_Type = E_Loop)
then
Output_End_Expected (Ins => False);
procedure Check_Bad_Layout is
begin
if RM_Column_Check and then Token_Is_At_Start_Of_Line
- and then Start_Column <= Scope.Table (Scope.Last).Ecol
+ and then Start_Column <= Scopes (Scope.Last).Ecol
then
Error_Msg_BC -- CODEFIX
("(style) incorrect layout");
Scope.Decrement_Last;
if Include_Subprogram_In_Messages
- and then Scope.Table (Scope.Last).Labl /= Error
+ and then Scopes (Scope.Last).Labl /= Error
then
- Current_Node := Scope.Table (Scope.Last).Labl;
+ Current_Node := Scopes (Scope.Last).Labl;
end if;
if Debug_Flag_P then
First_Non_Blank_Location);
end if;
- Scope.Table (Scope.Last).Junk := False;
- Scope.Table (Scope.Last).Node := Empty;
+ Scopes (Scope.Last).Junk := False;
+ Scopes (Scope.Last).Node := Empty;
if Debug_Flag_P then
Error_Msg_Uint_1 := UI_From_Int (Scope.Last);
SIS_Entry_Active : Boolean := False;
-- Set True to indicate that an entry is active (i.e. that a subprogram
- -- declaration has been encountered, and no body for this subprogram has
- -- been encountered). The remaining fields are valid only if this is True.
+ -- declaration has been encountered, and no body for this subprogram
+ -- has been encountered). The remaining variables other than
+ -- SIS_Aspect_Import_Seen are valid only if this is True.
+
+ SIS_Aspect_Import_Seen : Boolean := False;
+ -- If this is True when a subprogram declaration has been encountered, we
+ -- do not set SIS_Entry_Active, because the Import means there is no body.
+ -- Set False at the start of P_Subprogram, set True when an Import aspect
+ -- specification is seen, and used when P_Subprogram finds a subprogram
+ -- declaration. This is necessary because the aspects are parsed before
+ -- we know we have a subprogram declaration.
SIS_Labl : Node_Id;
-- Subprogram designator
Table_Increment => 100,
Table_Name => "Scope");
+ type Scope_Table_Entry_Ptr is access all Scope_Table_Entry;
+
+ function Scopes (Index : Int) return Scope_Table_Entry_Ptr;
+ -- Return the indicated Scope_Table_Entry. We use a pointer for
+ -- efficiency. Callers should not save the pointer, but should do things
+ -- like Scopes (Scope.Last).Something. Note that there is one place in
+ -- Par.Ch5 that indexes the stack out of bounds, and can't call this.
+
+ function Scopes (Index : Int) return Scope_Table_Entry_Ptr is
+ begin
+ pragma Assert (Index in Scope.First .. Scope.Last);
+ return Scope.Table (Index)'Unrestricted_Access;
+ end Scopes;
+
------------------------------------------
-- Table for Handling Suspicious Labels --
------------------------------------------
-- Push a new entry onto the scope stack. Scope.Last (the stack pointer)
-- is incremented. The Junk field is preinitialized to False. The caller
-- is expected to fill in all remaining entries of the new top stack
- -- entry at Scope.Table (Scope.Last).
+ -- entry at Scopes (Scope.Last).
procedure Pop_Scope_Stack;
-- Pop an entry off the top of the scope stack. Scope_Last (the scope
Compiler_State := Parsing;
Scope.Init;
Scope.Increment_Last;
- Scope.Table (0).Etyp := E_Dummy;
+ Scopes (0).Etyp := E_Dummy;
SIS_Entry_Active := False;
Last_Resync_Point := No_Location;