aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/par_sco.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@adacore.com>2010-06-16 16:30:48 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2010-06-16 18:30:48 +0200
commit25adc5fbf5c9ac211442106de78cba432212449c (patch)
treec15915818fefe732dbe57105e1e89f4316dbd193 /gcc/ada/par_sco.adb
parente1578ff354a8d03c4c46eaef6825d0b77885d6a3 (diff)
downloadgcc-25adc5fbf5c9ac211442106de78cba432212449c.zip
gcc-25adc5fbf5c9ac211442106de78cba432212449c.tar.gz
gcc-25adc5fbf5c9ac211442106de78cba432212449c.tar.bz2
get_scos.adb, [...]: Code clean up, update documentation.
* get_scos.adb, par_sco.adb, par_sco.ads, put_scos.adb, scos.adb, scos.ads, exp_ch4.adb, sem_warn.adb: Code clean up, update documentation. From-SVN: r160849
Diffstat (limited to 'gcc/ada/par_sco.adb')
-rw-r--r--gcc/ada/par_sco.adb552
1 files changed, 402 insertions, 150 deletions
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index 82ab9d6..5b5e4cf 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -104,8 +104,9 @@ package body Par_SCO is
-- If N is Empty, has no effect. Otherwise scans the tree for the node N,
-- to output any decisions it contains. T is one of IEPWX (for context of
-- expresion: if/exit when/pragma/while/expression). If T is other than X,
- -- then a decision is always present (at the very least a simple decision
- -- is present at the top level).
+ -- the node N is the conditional expression involved, and a decision is
+ -- always present (at the very least a simple decision is present at the
+ -- top level).
procedure Process_Decisions (L : List_Id; T : Character);
-- Calls above procedure for each element of the list L
@@ -115,15 +116,18 @@ package body Par_SCO is
C2 : Character;
From : Source_Ptr;
To : Source_Ptr;
+ Node : Node_Id;
Last : Boolean);
-- Append an entry to SCO_Table with fields set as per arguments
procedure Traverse_Declarations_Or_Statements (L : List_Id);
+ procedure Traverse_Generic_Instantiation (N : Node_Id);
procedure Traverse_Generic_Package_Declaration (N : Node_Id);
procedure Traverse_Handled_Statement_Sequence (N : Node_Id);
procedure Traverse_Package_Body (N : Node_Id);
procedure Traverse_Package_Declaration (N : Node_Id);
procedure Traverse_Subprogram_Body (N : Node_Id);
+ procedure Traverse_Subprogram_Declaration (N : Node_Id);
-- Traverse the corresponding construct, generating SCO table entries
procedure Write_SCOs_To_ALI_File is new Put_SCOs;
@@ -228,6 +232,11 @@ package body Par_SCO is
Write_Str (" False");
end if;
+ if Present (T.Node) then
+ Write_Str (" Node = ");
+ Write_Int (Int (T.Node));
+ end if;
+
Write_Eol;
end;
end loop;
@@ -299,8 +308,7 @@ package body Par_SCO is
function Is_Logical_Operator (N : Node_Id) return Boolean is
begin
- return Nkind_In (N, N_Op_Xor,
- N_Op_Not,
+ return Nkind_In (N, N_Op_Not,
N_And_Then,
N_Or_Else);
end Is_Logical_Operator;
@@ -327,6 +335,17 @@ package body Par_SCO is
procedure Process_Decisions (N : Node_Id; T : Character) is
+ Mark : Nat;
+ -- This is used to mark the location of a decision sequence in the SCO
+ -- table. We use it for backing out a simple decision in an expression
+ -- context that contains only NOT operators.
+
+ X_Not_Decision : Boolean;
+ -- This flag keeps track of whether a decision sequence in the SCO table
+ -- contains only NOT operators, and is for an expression context (T=X).
+ -- The flag will be set False if T is other than X, or if an operator
+ -- other than NOT is in the sequence.
+
function Process_Node (N : Node_Id) return Traverse_Result;
-- Processes one node in the traversal, looking for logical operators,
-- and if one is found, outputs the appropriate table entries.
@@ -340,13 +359,15 @@ package body Par_SCO is
-- Process_Decision_Operand, because we can't get decisions mixed up in
-- the global table. Call has no effect if N is Empty.
- procedure Output_Element (N : Node_Id; T : Character);
+ procedure Output_Element (N : Node_Id);
-- Node N is an operand of a logical operator that is not itself a
-- logical operator, or it is a simple decision. This routine outputs
- -- the table entry for the element, with C1 set to T (' ' for one of
- -- the elements of a complex decision, or 'I'/'W'/'E' for a simple
- -- decision (from an IF, WHILE, or EXIT WHEN). Last is set to False,
- -- and an entry is made in the condition hash table.
+ -- the table entry for the element, with C1 set to ' '. Last is set
+ -- False, and an entry is made in the condition hash table.
+
+ procedure Output_Header (T : Character);
+ -- Outputs a decision header node. T is I/W/E/P for IF/WHILE/EXIT WHEN/
+ -- PRAGMA, and 'X' for the expression case.
procedure Process_Decision_Operand (N : Node_Id);
-- This is called on node N, the top level node of a decision, or on one
@@ -376,16 +397,20 @@ package body Par_SCO is
else
L := Left_Opnd (N);
- if Nkind (N) = N_Op_Xor then
- C := '^';
- elsif Nkind_In (N, N_Op_Or, N_Or_Else) then
+ if Nkind_In (N, N_Op_Or, N_Or_Else) then
C := '|';
else
C := '&';
end if;
end if;
- Set_Table_Entry (C, ' ', No_Location, No_Location, False);
+ Set_Table_Entry
+ (C1 => C,
+ C2 => ' ',
+ From => Sloc (N),
+ To => No_Location,
+ Node => Empty,
+ Last => False);
Output_Decision_Operand (L);
Output_Decision_Operand (Right_Opnd (N));
@@ -393,7 +418,7 @@ package body Par_SCO is
-- Not a logical operator
else
- Output_Element (N, ' ');
+ Output_Element (N);
end if;
end Output_Decision_Operand;
@@ -401,15 +426,79 @@ package body Par_SCO is
-- Output_Element --
--------------------
- procedure Output_Element (N : Node_Id; T : Character) is
+ procedure Output_Element (N : Node_Id) is
FSloc : Source_Ptr;
LSloc : Source_Ptr;
begin
Sloc_Range (N, FSloc, LSloc);
- Set_Table_Entry (T, 'c', FSloc, LSloc, False);
+ Set_Table_Entry
+ (C1 => ' ',
+ C2 => 'c',
+ From => FSloc,
+ To => LSloc,
+ Node => Empty,
+ Last => False);
Condition_Hash_Table.Set (FSloc, SCO_Table.Last);
end Output_Element;
+ -------------------
+ -- Output_Header --
+ -------------------
+
+ procedure Output_Header (T : Character) is
+ begin
+ case T is
+ when 'I' | 'E' | 'W' =>
+
+ -- For IF, EXIT, WHILE, the token SLOC can be found from
+ -- the SLOC of the parent of the expression.
+
+ Set_Table_Entry
+ (C1 => T,
+ C2 => ' ',
+ From => Sloc (Parent (N)),
+ To => No_Location,
+ Node => Empty,
+ Last => False);
+
+ when 'P' =>
+
+ -- For PRAGMA, we must record the pragma node. Argument N
+ -- is the pragma argument, and we have to go up two levels
+ -- (through the pragma argument association) to get to the
+ -- pragma node itself.
+
+ declare
+ Pnode : constant Node_Id := Parent (Parent (N));
+ begin
+ Set_Table_Entry
+ (C1 => 'P',
+ C2 => ' ',
+ From => Sloc (Pnode),
+ To => No_Location,
+ Node => Pnode,
+ Last => False);
+ end;
+
+ when 'X' =>
+
+ -- For an expression, no Sloc
+
+ Set_Table_Entry
+ (C1 => 'X',
+ C2 => ' ',
+ From => No_Location,
+ To => No_Location,
+ Node => Empty,
+ Last => False);
+
+ -- No other possibilities
+
+ when others =>
+ raise Program_Error;
+ end case;
+ end Output_Header;
+
------------------------------
-- Process_Decision_Operand --
------------------------------
@@ -419,6 +508,7 @@ package body Par_SCO is
if Is_Logical_Operator (N) then
if Nkind (N) /= N_Op_Not then
Process_Decision_Operand (Left_Opnd (N));
+ X_Not_Decision := False;
end if;
Process_Decision_Operand (Right_Opnd (N));
@@ -439,9 +529,9 @@ package body Par_SCO is
-- Logical operators, output table entries and then process
-- operands recursively to deal with nested conditions.
- when N_And_Then |
- N_Or_Else |
- N_Op_Not =>
+ when N_And_Then |
+ N_Or_Else |
+ N_Op_Not =>
declare
T : Character;
@@ -458,15 +548,26 @@ package body Par_SCO is
-- Output header for sequence
- Set_Table_Entry (T, ' ', No_Location, No_Location, False);
+ X_Not_Decision := T = 'X' and then Nkind (N) = N_Op_Not;
+ Mark := SCO_Table.Last;
+ Output_Header (T);
-- Output the decision
Output_Decision_Operand (N);
- -- Change Last in last table entry to True to mark end
+ -- If the decision was in an expression context (T = 'X')
+ -- and contained only NOT operators, then we don't output
+ -- it, so delete it.
- SCO_Table.Table (SCO_Table.Last).Last := True;
+ if X_Not_Decision then
+ SCO_Table.Set_Last (Mark);
+
+ -- Otherwise, set Last in last table entry to mark end
+
+ else
+ SCO_Table.Table (SCO_Table.Last).Last := True;
+ end if;
-- Process any embedded decisions
@@ -476,7 +577,7 @@ package body Par_SCO is
-- Conditional expression, processed like an if statement
- when N_Conditional_Expression =>
+ when N_Conditional_Expression =>
declare
Cond : constant Node_Id := First (Expressions (N));
Thnx : constant Node_Id := Next (Cond);
@@ -508,11 +609,12 @@ package body Par_SCO is
-- See if we have simple decision at outer level and if so then
-- generate the decision entry for this simple decision. A simple
-- decision is a boolean expression (which is not a logical operator
- -- or short circuit form) appearing as the operand of an IF, WHILE
- -- or EXIT WHEN construct.
+ -- or short circuit form) appearing as the operand of an IF, WHILE,
+ -- EXIT WHEN, or special PRAGMA construct.
if T /= 'X' and then not Is_Logical_Operator (N) then
- Output_Element (N, T);
+ Output_Header (T);
+ Output_Element (N);
-- Change Last in last table entry to True to mark end of
-- sequence, which is this case is only one element long.
@@ -671,6 +773,9 @@ package body Par_SCO is
if Nkind (Lu) = N_Subprogram_Body then
Traverse_Subprogram_Body (Lu);
+ elsif Nkind (Lu) = N_Subprogram_Declaration then
+ Traverse_Subprogram_Declaration (Lu);
+
elsif Nkind (Lu) = N_Package_Declaration then
Traverse_Package_Declaration (Lu);
@@ -680,12 +785,14 @@ package body Par_SCO is
elsif Nkind (Lu) = N_Generic_Package_Declaration then
Traverse_Generic_Package_Declaration (Lu);
- -- For anything else, the only issue is default expressions for
- -- parameters, where we have to worry about possible embedded decisions
- -- but nothing else.
+ elsif Nkind (Lu) in N_Generic_Instantiation then
+ Traverse_Generic_Instantiation (Lu);
+
+ -- All other cases of compilation units (e.g. renamings), generate
+ -- no SCO information.
else
- Process_Decisions (Lu, 'X');
+ null;
end if;
-- Make entry for new unit in unit tables, we will fill in the file
@@ -704,11 +811,20 @@ package body Par_SCO is
-- Set_SCO_Condition --
-----------------------
- procedure Set_SCO_Condition (First_Loc : Source_Ptr; Typ : Character) is
- Index : constant Nat := Condition_Hash_Table.Get (First_Loc);
+ procedure Set_SCO_Condition (Cond : Node_Id; Val : Boolean) is
+ Orig : constant Node_Id := Original_Node (Cond);
+ Index : Nat;
+ Start : Source_Ptr;
+ Dummy : Source_Ptr;
+
+ Constant_Condition_Code : constant array (Boolean) of Character :=
+ (False => 'f', True => 't');
begin
+ Sloc_Range (Orig, Start, Dummy);
+ Index := Condition_Hash_Table.Get (Start);
+
if Index /= 0 then
- SCO_Table.Table (Index).C2 := Typ;
+ SCO_Table.Table (Index).C2 := Constant_Condition_Code (Val);
end if;
end Set_SCO_Condition;
@@ -721,6 +837,7 @@ package body Par_SCO is
C2 : Character;
From : Source_Ptr;
To : Source_Ptr;
+ Node : Node_Id;
Last : Boolean)
is
function To_Source_Location (S : Source_Ptr) return Source_Location;
@@ -749,6 +866,7 @@ package body Par_SCO is
C2 => C2,
From => To_Source_Location (From),
To => To_Source_Location (To),
+ Node => Node,
Last => Last);
end Set_Table_Entry;
@@ -756,34 +874,73 @@ package body Par_SCO is
-- Traverse_Declarations_Or_Statements --
-----------------------------------------
+ -- Tables used by Traverse_Declarations_Or_Statements for temporarily
+ -- holding statement and decision entries. These are declared globally
+ -- since they are shared by recursive calls to this procedure.
+
+ type SC_Entry is record
+ From : Source_Ptr;
+ To : Source_Ptr;
+ Typ : Character;
+ end record;
+ -- Used to store a single entry in the following table, From:To represents
+ -- the range of entries in the CS line entry, and typ is the type, with
+ -- space meaning that no type letter will accompany the entry.
+
+ package SC is new Table.Table (
+ Table_Component_Type => SC_Entry,
+ Table_Index_Type => Nat,
+ Table_Low_Bound => 1,
+ Table_Initial => 1000,
+ Table_Increment => 200,
+ Table_Name => "SCO_SC");
+ -- Used to store statement components for a CS entry to be output
+ -- as a result of the call to this procedure. SC.Last is the last
+ -- entry stored, so the current statement sequence is represented
+ -- by SC_Array (SC_First .. SC.Last), where SC_First is saved on
+ -- entry to each recursive call to the routine.
+ --
+ -- Extend_Statement_Sequence adds an entry to this array, and then
+ -- Set_Statement_Entry clears the entries starting with SC_First,
+ -- copying these entries to the main SCO output table. The reason that
+ -- we do the temporary caching of results in this array is that we want
+ -- the SCO table entries for a given CS line to be contiguous, and the
+ -- processing may output intermediate entries such as decision entries.
+
+ type SD_Entry is record
+ Nod : Node_Id;
+ Lst : List_Id;
+ Typ : Character;
+ end record;
+ -- Used to store a single entry in the following table. Nod is the node to
+ -- be searched for decisions for the case of Process_Decisions_Defer with a
+ -- node argument (with Lst set to No_List. Lst is the list to be searched
+ -- for decisions for the case of Process_Decisions_Defer with a List
+ -- argument (in which case Nod is set to Empty).
+
+ package SD is new Table.Table (
+ Table_Component_Type => SD_Entry,
+ Table_Index_Type => Nat,
+ Table_Low_Bound => 1,
+ Table_Initial => 1000,
+ Table_Increment => 200,
+ Table_Name => "SCO_SD");
+ -- Used to store possible decision information. Instead of calling the
+ -- Process_Decisions procedures directly, we call Process_Decisions_Defer,
+ -- which simply stores the arguments in this table. Then when we clear
+ -- out a statement sequence using Set_Statement_Entry, after generating
+ -- the CS lines for the statements, the entries in this table result in
+ -- calls to Process_Decision. The reason for doing things this way is to
+ -- ensure that decisions are output after the CS line for the statements
+ -- in which the decisions occur.
+
procedure Traverse_Declarations_Or_Statements (L : List_Id) is
N : Node_Id;
Dummy : Source_Ptr;
- type SC_Entry is record
- From : Source_Ptr;
- To : Source_Ptr;
- Typ : Character;
- end record;
- -- Used to store a single entry in the following array
-
- SC_Array : array (Nat range 1 .. 10_000) of SC_Entry;
- SC_Last : Nat;
- -- Used to store statement components for a CS entry to be output
- -- as a result of the call to this procedure. SC_Last is the last
- -- entry stored, so the current statement sequence is represented
- -- by SC_Array (1 .. SC_Last). Extend_Statement_Sequence adds an
- -- entry to this array, and Set_Statement_Entry clears it, copying
- -- the entries to the main SCO output table. The reason that we do
- -- the temporary caching of results in this array is that we want
- -- the SCO table entries for a given CS line to be contiguous, and
- -- the processing may output intermediate entries such as decision
- -- entries. Note that the limit of 10_000 here is arbitrary, but does
- -- not cause any trouble, if we encounter more than 10_000 statements
- -- we simply break the current CS sequence at that point, which is
- -- harmless, since this is only used for back annotation and it is
- -- not critical that back annotation always work in all cases. Anyway
- -- exceeding 10,000 statements in a basic block is very unlikely.
+ SC_First : constant Nat := SC.Last + 1;
+ SD_First : constant Nat := SD.Last + 1;
+ -- Record first entries used in SC/SD at this recursive level
procedure Extend_Statement_Sequence (N : Node_Id; Typ : Character);
-- Extend the current statement sequence to encompass the node N. Typ
@@ -806,32 +963,70 @@ package body Par_SCO is
-- called when we find a statement or declaration that generates its
-- own table entry, so that we must end the current statement sequence.
+ procedure Process_Decisions_Defer (N : Node_Id; T : Character);
+ pragma Inline (Process_Decisions_Defer);
+ -- This routine is logically the same as Process_Decisions, except that
+ -- the arguments are saved in the SD table, for later processing when
+ -- Set_Statement_Entry is called, which goes through the saved entries
+ -- making the corresponding calls to Process_Decision.
+
+ procedure Process_Decisions_Defer (L : List_Id; T : Character);
+ pragma Inline (Process_Decisions_Defer);
+ -- Same case for list arguments, deferred call to Process_Decisions
+
-------------------------
-- Set_Statement_Entry --
-------------------------
procedure Set_Statement_Entry is
- C1 : Character;
+ C1 : Character;
+ SC_Last : constant Int := SC.Last;
+ SD_Last : constant Int := SD.Last;
begin
- if SC_Last /= 0 then
- for J in 1 .. SC_Last loop
- if J = 1 then
- C1 := 'S';
- else
- C1 := 's';
- end if;
+ -- Output statement entries from saved entries in SC table
+
+ for J in SC_First .. SC_Last loop
+ if J = SC_First then
+ C1 := 'S';
+ else
+ C1 := 's';
+ end if;
+ declare
+ SCE : SC_Entry renames SC.Table (J);
+ begin
Set_Table_Entry
(C1 => C1,
- C2 => SC_Array (J).Typ,
- From => SC_Array (J).From,
- To => SC_Array (J).To,
+ C2 => SCE.Typ,
+ From => SCE.From,
+ To => SCE.To,
+ Node => Empty,
Last => (J = SC_Last));
- end loop;
+ end;
+ end loop;
- SC_Last := 0;
- end if;
+ -- Clear out used section of SC table
+
+ SC.Set_Last (SC_First - 1);
+
+ -- Output any embedded decisions
+
+ for J in SD_First .. SD_Last loop
+ declare
+ SDE : SD_Entry renames SD.Table (J);
+ begin
+ if Present (SDE.Nod) then
+ Process_Decisions (SDE.Nod, SDE.Typ);
+ else
+ Process_Decisions (SDE.Lst, SDE.Typ);
+ end if;
+ end;
+ end loop;
+
+ -- Clear out used section of SD table
+
+ SD.Set_Last (SD_First - 1);
end Set_Statement_Entry;
-------------------------------
@@ -839,20 +1034,11 @@ package body Par_SCO is
-------------------------------
procedure Extend_Statement_Sequence (N : Node_Id; Typ : Character) is
+ F : Source_Ptr;
+ T : Source_Ptr;
begin
- -- Clear out statement sequence if array full
-
- if SC_Last = SC_Array'Last then
- Set_Statement_Entry;
- else
- SC_Last := SC_Last + 1;
- end if;
-
- -- Record new entry
-
- Sloc_Range
- (N, SC_Array (SC_Last).From, SC_Array (SC_Last).To);
- SC_Array (SC_Last).Typ := Typ;
+ Sloc_Range (N, F, T);
+ SC.Append ((F, T, Typ));
end Extend_Statement_Sequence;
procedure Extend_Statement_Sequence
@@ -860,27 +1046,32 @@ package body Par_SCO is
To : Node_Id;
Typ : Character)
is
+ F : Source_Ptr;
+ T : Source_Ptr;
begin
- -- Clear out statement sequence if array full
+ Sloc_Range (From, F, Dummy);
+ Sloc_Range (To, Dummy, T);
+ SC.Append ((F, T, Typ));
+ end Extend_Statement_Sequence;
- if SC_Last = SC_Array'Last then
- Set_Statement_Entry;
- else
- SC_Last := SC_Last + 1;
- end if;
+ -----------------------------
+ -- Process_Decisions_Defer --
+ -----------------------------
- -- Make new entry
+ procedure Process_Decisions_Defer (N : Node_Id; T : Character) is
+ begin
+ SD.Append ((N, No_List, T));
+ end Process_Decisions_Defer;
- Sloc_Range (From, SC_Array (SC_Last).From, Dummy);
- Sloc_Range (To, Dummy, SC_Array (SC_Last).To);
- SC_Array (SC_Last).Typ := Typ;
- end Extend_Statement_Sequence;
+ procedure Process_Decisions_Defer (L : List_Id; T : Character) is
+ begin
+ SD.Append ((Empty, L, T));
+ end Process_Decisions_Defer;
-- Start of processing for Traverse_Declarations_Or_Statements
begin
if Is_Non_Empty_List (L) then
- SC_Last := 0;
-- Loop through statements or declarations
@@ -915,17 +1106,18 @@ package body Par_SCO is
-- Subprogram declaration
when N_Subprogram_Declaration =>
- Set_Statement_Entry;
- Process_Decisions
+ Process_Decisions_Defer
(Parameter_Specifications (Specification (N)), 'X');
+ Set_Statement_Entry;
-- Generic subprogram declaration
when N_Generic_Subprogram_Declaration =>
- Set_Statement_Entry;
- Process_Decisions (Generic_Formal_Declarations (N), 'X');
- Process_Decisions
+ Process_Decisions_Defer
+ (Generic_Formal_Declarations (N), 'X');
+ Process_Decisions_Defer
(Parameter_Specifications (Specification (N)), 'X');
+ Set_Statement_Entry;
-- Subprogram_Body
@@ -940,8 +1132,8 @@ package body Par_SCO is
when N_Exit_Statement =>
Extend_Statement_Sequence (N, ' ');
+ Process_Decisions_Defer (Condition (N), 'E');
Set_Statement_Entry;
- Process_Decisions (Condition (N), 'E');
-- Label, which breaks the current statement sequence, but the
-- label itself is not included in the next statement sequence,
@@ -963,16 +1155,33 @@ package body Par_SCO is
when N_If_Statement =>
Extend_Statement_Sequence (N, Condition (N), 'I');
+ Process_Decisions_Defer (Condition (N), 'I');
Set_Statement_Entry;
- Process_Decisions (Condition (N), 'I');
+
+ -- Now we traverse the statements in the THEN part
+
Traverse_Declarations_Or_Statements (Then_Statements (N));
+ -- Loop through ELSIF parts if present
+
if Present (Elsif_Parts (N)) then
declare
Elif : Node_Id := First (Elsif_Parts (N));
+
begin
while Present (Elif) loop
- Process_Decisions (Condition (Elif), 'I');
+
+ -- We generate a statement sequence for the
+ -- construct "ELSIF condition", so that we have
+ -- a statement for the resulting decisions.
+
+ Extend_Statement_Sequence
+ (Elif, Condition (Elif), 'I');
+ Process_Decisions_Defer (Condition (Elif), 'I');
+ Set_Statement_Entry;
+
+ -- Traverse the statements in the ELSIF
+
Traverse_Declarations_Or_Statements
(Then_Statements (Elif));
Next (Elif);
@@ -980,6 +1189,8 @@ package body Par_SCO is
end;
end if;
+ -- Finally traverse the ELSE statements if present
+
Traverse_Declarations_Or_Statements (Else_Statements (N));
-- Case statement, which breaks the current statement sequence,
@@ -987,14 +1198,13 @@ package body Par_SCO is
when N_Case_Statement =>
Extend_Statement_Sequence (N, Expression (N), 'C');
+ Process_Decisions_Defer (Expression (N), 'X');
Set_Statement_Entry;
- Process_Decisions (Expression (N), 'X');
-- Process case branches
declare
Alt : Node_Id;
-
begin
Alt := First (Alternatives (N));
while Present (Alt) loop
@@ -1017,22 +1227,17 @@ package body Par_SCO is
when N_Simple_Return_Statement =>
Extend_Statement_Sequence (N, ' ');
+ Process_Decisions_Defer (Expression (N), 'X');
Set_Statement_Entry;
- Process_Decisions (Expression (N), 'X');
-- Extended return statement
when N_Extended_Return_Statement =>
- declare
- Odecl : constant Node_Id :=
- First (Return_Object_Declarations (N));
- begin
- if Present (Expression (Odecl)) then
- Extend_Statement_Sequence
- (N, Expression (Odecl), 'R');
- Process_Decisions (Expression (Odecl), 'X');
- end if;
- end;
+ Extend_Statement_Sequence
+ (N, Last (Return_Object_Declarations (N)), 'R');
+ Process_Decisions_Defer
+ (Return_Object_Declarations (N), 'X');
+ Set_Statement_Entry;
Traverse_Handled_Statement_Sequence
(Handled_Statement_Sequence (N));
@@ -1057,13 +1262,13 @@ package body Par_SCO is
if Present (Condition (ISC)) then
Extend_Statement_Sequence (N, ISC, 'W');
- Process_Decisions (Condition (ISC), 'W');
+ Process_Decisions_Defer (Condition (ISC), 'W');
-- For statement
else
Extend_Statement_Sequence (N, ISC, 'F');
- Process_Decisions
+ Process_Decisions_Defer
(Loop_Parameter_Specification (ISC), 'X');
end if;
end;
@@ -1077,42 +1282,55 @@ package body Par_SCO is
when N_Pragma =>
Extend_Statement_Sequence (N, 'P');
- -- For pragmas Assert, Check, Precondition, and
- -- Postcondition, we generate decision entries for the
- -- condition only if the pragma is enabled. For now, we just
- -- check Assertions_Enabled, which will be set to reflect
- -- the presence of -gnata.
+ -- Processing depends on the kind of pragma
- -- Later we should move processing of the relevant pragmas
- -- to Par_Prag, and properly set the flag Pragma_Enabled at
- -- parse time, so that we can check this flag instead ???
+ case Pragma_Name (N) is
+ when Name_Assert |
+ Name_Check |
+ Name_Precondition |
+ Name_Postcondition =>
- -- For all other pragmas, we always generate decision
- -- entries for any embedded expressions.
+ -- For Assert/Check/Precondition/Postcondition, we
+ -- must generate a P entry for the decision. Note that
+ -- this is done unconditionally at this stage. Output
+ -- for disabled pragmas is suppressed later on, when
+ -- we output the decision line in Put_SCOs.
- declare
- Nam : constant Name_Id :=
- Chars (Pragma_Identifier (N));
- Arg : Node_Id := First (Pragma_Argument_Associations (N));
- begin
- case Nam is
- when Name_Assert |
- Name_Check |
- Name_Precondition |
- Name_Postcondition =>
+ declare
+ Nam : constant Name_Id :=
+ Chars (Pragma_Identifier (N));
+ Arg : Node_Id :=
+ First (Pragma_Argument_Associations (N));
+ begin
if Nam = Name_Check then
Next (Arg);
end if;
- if Assertions_Enabled then
- Process_Decisions (Expression (Arg), 'P');
- end if;
+ Process_Decisions_Defer (Expression (Arg), 'P');
+ end;
- when others =>
- Process_Decisions (N, 'X');
- end case;
- end;
+ -- For all other pragmas, we generate decision entries
+ -- for any embedded expressions.
+
+ when others =>
+ Process_Decisions_Defer (N, 'X');
+ end case;
+
+ -- Object declaration. Ignored if Prev_Ids is set, since the
+ -- parser generates multiple instances of the whole declaration
+ -- if there is more than one identifier declared, and we only
+ -- want one entry in the SCO's, so we take the first, for which
+ -- Prev_Ids is False.
+
+ when N_Object_Declaration =>
+ if not Prev_Ids (N) then
+ Extend_Statement_Sequence (N, 'o');
+
+ if Has_Decision (N) then
+ Process_Decisions_Defer (N, 'X');
+ end if;
+ end if;
-- All other cases, which extend the current statement sequence
-- but do not terminate it, even if they have nested decisions.
@@ -1135,9 +1353,6 @@ package body Par_SCO is
when N_Subtype_Declaration =>
Typ := 's';
- when N_Object_Declaration =>
- Typ := 'o';
-
when N_Renaming_Declaration =>
Typ := 'r';
@@ -1154,7 +1369,7 @@ package body Par_SCO is
-- Process any embedded decisions
if Has_Decision (N) then
- Process_Decisions (N, 'X');
+ Process_Decisions_Defer (N, 'X');
end if;
end case;
@@ -1165,6 +1380,31 @@ package body Par_SCO is
end if;
end Traverse_Declarations_Or_Statements;
+ ------------------------------------
+ -- Traverse_Generic_Instantiation --
+ ------------------------------------
+
+ procedure Traverse_Generic_Instantiation (N : Node_Id) is
+ First : Source_Ptr;
+ Last : Source_Ptr;
+
+ begin
+ -- First we need a statement entry to cover the instantiation
+
+ Sloc_Range (N, First, Last);
+ Set_Table_Entry
+ (C1 => 'S',
+ C2 => ' ',
+ From => First,
+ To => Last,
+ Node => Empty,
+ Last => True);
+
+ -- Now output any embedded decisions
+
+ Process_Decisions (N, 'X');
+ end Traverse_Generic_Instantiation;
+
------------------------------------------
-- Traverse_Generic_Package_Declaration --
------------------------------------------
@@ -1232,4 +1472,16 @@ package body Par_SCO is
Traverse_Handled_Statement_Sequence (Handled_Statement_Sequence (N));
end Traverse_Subprogram_Body;
+ -------------------------------------
+ -- Traverse_Subprogram_Declaration --
+ -------------------------------------
+
+ procedure Traverse_Subprogram_Declaration (N : Node_Id) is
+ ADN : constant Node_Id := Aux_Decls_Node (Parent (N));
+ begin
+ Traverse_Declarations_Or_Statements (Config_Pragmas (ADN));
+ Traverse_Declarations_Or_Statements (Declarations (ADN));
+ Traverse_Declarations_Or_Statements (Pragmas_After (ADN));
+ end Traverse_Subprogram_Declaration;
+
end Par_SCO;