aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTucker Taft <taft@adacore.com>2024-12-04 16:22:10 +0000
committerMarc Poulhiès <dkm@gcc.gnu.org>2025-01-03 16:39:13 +0100
commit98e37c6ca5a0b3dd2729dcf3e79df40edb020f52 (patch)
tree2be96bc8bd5483c1efca9f794bfa58d4a082a0b5 /gcc
parent0a6736ef366af6bcd7e25567919202fd6c40b7c9 (diff)
downloadgcc-98e37c6ca5a0b3dd2729dcf3e79df40edb020f52.zip
gcc-98e37c6ca5a0b3dd2729dcf3e79df40edb020f52.tar.gz
gcc-98e37c6ca5a0b3dd2729dcf3e79df40edb020f52.tar.bz2
ada: Add parentheses in expressions involving combinations of and & or
In the Expression_Image function, we were not inserting parentheses properly when there was a sequence of and and or operators, even though Ada requires such parentheses to show the correct order of association. gcc/ada/ChangeLog: * pprint.adb (Expression_Image): In local function Expr_Name add a No_Parens flag and define a subtype Not_Associative to represent the short-circuit operations and And/Or/Xor. Insert parentheses to separate the subexpressions when different "Not_Associative" operations occur in a sequence.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/pprint.adb53
1 files changed, 46 insertions, 7 deletions
diff --git a/gcc/ada/pprint.adb b/gcc/ada/pprint.adb
index b5935fc..5958a6b4 100644
--- a/gcc/ada/pprint.adb
+++ b/gcc/ada/pprint.adb
@@ -57,12 +57,16 @@ package body Pprint is
function Expr_Name
(Expr : Node_Id;
Take_Prefix : Boolean := True;
- Expand_Type : Boolean := True) return String;
+ Expand_Type : Boolean := True;
+ No_Parens : Boolean := False) return String;
-- Return string corresponding to Expr. If no string can be extracted,
-- return "...". If Take_Prefix is True, go back to prefix when needed,
-- otherwise only consider the right-hand side of an expression. If
-- Expand_Type is True and Expr is a type, try to expand Expr (an
-- internally generated type) into a user understandable name.
+ -- If No_Parens is True, then suppress creating parentheses
+ -- around expression. If False, check to see whether expression
+ -- should be parenthesized.
function Count_Parentheses (S : String; C : Character) return Natural
with Pre => C in '(' | ')';
@@ -70,6 +74,8 @@ package body Pprint is
-- to string S for getting a correctly parenthesized result. For C = '('
-- this means prepending the character, for C = ')' this means appending
-- the character.
+ -- In other words, count the number of missing instances of C,
+ -- but never return less than zero.
function Fix_Parentheses (S : String) return String;
-- Counts the number of required opening and closing parentheses in S to
@@ -101,6 +107,7 @@ package body Pprint is
Elmt : Node_Id;
Printed_Elmts : Natural := 0;
+ List_Len : constant Natural := Natural (List_Length (List));
begin
-- Give up if the printed list is too deep
@@ -146,7 +153,8 @@ package body Pprint is
-- Print expression itself as "12345"
else
- Append (Buf, Expr_Name (Elmt));
+ Append (Buf, Expr_Name (Elmt, No_Parens => List_Len = 1));
+ -- Suppress parens if is the only parameter.
end if;
Next (Elmt);
@@ -178,9 +186,32 @@ package body Pprint is
function Expr_Name
(Expr : Node_Id;
Take_Prefix : Boolean := True;
- Expand_Type : Boolean := True) return String
+ Expand_Type : Boolean := True;
+ No_Parens : Boolean := False) return String
is
+ -- Define subtype matching logical operations
+ -- and [then], or [else], and xor.
+ subtype Not_Associative is N_Subexpr
+ with Static_Predicate =>
+ Not_Associative in
+ N_Short_Circuit | N_Op_And | N_Op_Or | N_Op_Xor;
begin
+ if not No_Parens
+ and then
+ (Paren_Count (Expr) > 0
+ or else
+ (Nkind (Expr) in Not_Associative
+ and then
+ Nkind (Parent (Expr)) in Not_Associative
+ and then
+ Nkind (Parent (Expr)) /= Nkind (Expr)))
+ then
+ -- Parentheses are needed
+ return '(' &
+ Expr_Name (Expr, Take_Prefix, Expand_Type, No_Parens => True) &
+ ')';
+ end if;
+
Num_Elements := Num_Elements + 1;
if Num_Elements > Max_Expr_Elements then
@@ -589,7 +620,9 @@ package body Pprint is
return "abs " & Expr_Name (Right_Opnd (Expr));
when N_Op_Not =>
- return "not (" & Expr_Name (Right_Opnd (Expr)) & ")";
+ return "not (" &
+ Expr_Name (Right_Opnd (Expr), No_Parens => True) &
+ ")";
when N_Type_Conversion =>
@@ -608,7 +641,9 @@ package body Pprint is
Is_Modular_Integer_Type (Etype (Expression (Expr)))
then
return Expr_Name (Subtype_Mark (Expr)) &
- "(" & Expr_Name (Expression (Expr)) & ")";
+ "(" &
+ Expr_Name (Expression (Expr), No_Parens => True) &
+ ")";
else
return Expr_Name (Expression (Expr));
end if;
@@ -636,7 +671,9 @@ package body Pprint is
& List_Name (Parameter_Associations (Expr))
& "))";
else
- return '(' & Expr_Name (Name (Expr)) & ')';
+ return '(' &
+ Expr_Name (Name (Expr), No_Parens => True) &
+ ')';
end if;
elsif Present (Parameter_Associations (Expr)) then
return
@@ -676,6 +713,8 @@ package body Pprint is
-- Process next character Ch and update the number Count of C
-- characters to add for correct parenthesizing, where D is the
-- opposite parenthesis.
+ -- In other words, count the number of missing instances of C,
+ -- or equivalently, the number of unmatched instances of D.
---------------
-- Next_Char --
@@ -775,7 +814,7 @@ package body Pprint is
or else Opt.Debug_Generated_Code
then
declare
- S : constant String := Expr_Name (Expr);
+ S : constant String := Expr_Name (Expr, No_Parens => True);
begin
if S = "..." then
return Default;