diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-08 12:44:17 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-08 12:44:17 +0000 |
commit | 0a5976bdd80a0a80ce330c644426f72b4a6a13ce (patch) | |
tree | a2a551bee270f1913fac097232a8bb8e6d194b68 /gcc/ada/exp_ch4.adb | |
parent | 99dd12bf89198b78b45619de7da6b58b403dd1bb (diff) | |
download | gcc-0a5976bdd80a0a80ce330c644426f72b4a6a13ce.tar.gz |
2009-04-08 Emmanuel Briot <briot@adacore.com>
* prj-nmsc.adb (Check_File, Process_Sources_In_Multi_Language_Mode):
avoid copies of Source_Data variables when possible, since these
involve calls to memcpy() which are done too many times.
2009-04-08 Robert Dewar <dewar@adacore.com>
* exp_ch4.adb (Expand_Concatenate): Clean up code
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145721 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r-- | gcc/ada/exp_ch4.adb | 105 |
1 files changed, 61 insertions, 44 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 771efd49dd2..fa8ef46389e 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -62,7 +62,6 @@ with Sem_Warn; use Sem_Warn; with Sinfo; use Sinfo; with Snames; use Snames; with Stand; use Stand; -with Stringt; use Stringt; with Targparm; use Targparm; with Tbuild; use Tbuild; with Ttypes; use Ttypes; @@ -2168,7 +2167,14 @@ package body Exp_Ch4 is -- Number of concatenation operands including possibly null operands NN : Nat := 0; - -- Number of operands excluding any known to be null + -- Number of operands excluding any known to be null, except that the + -- last operand is always retained, in case it provides the bounds for + -- a null result. + + Opnd : Node_Id; + -- Current operand being processed in the loop through operands. After + -- this loop is complete, always contains the last operand (which is not + -- the same as Operands (NN), since null operands are skipped). -- Arrays describing the operands, only the first NN entries of each -- array are set (NN < N when we exclude known null operands). @@ -2177,7 +2183,8 @@ package body Exp_Ch4 is -- True if length of corresponding operand known at compile time Operands : array (1 .. N) of Node_Id; - -- Set to the corresponding entry in the Opnds list + -- Set to the corresponding entry in the Opnds list (but note that null + -- operands are excluded, so not all entries in the list are stored). Fixed_Length : array (1 .. N) of Uint; -- Set to length of operand. Entries in this array are set only if the @@ -2188,11 +2195,6 @@ package body Exp_Ch4 is -- where the bound is known at compile time, else actual lower bound. -- The operand low bound is of type Ityp. - Opnd_High_Bound : array (1 .. N) of Node_Id; - -- Set to upper bound of operand. Either an integer literal in the case - -- where the bound is known at compile time, else actual upper bound. - -- The operand bound is of type Ityp. - Var_Length : array (1 .. N) of Entity_Id; -- Set to an entity of type Natural that contains the length of an -- operand whose length is not known at compile time. Entries in this @@ -2211,6 +2213,12 @@ package body Exp_Ch4 is -- This is either an integer literal node, or an identifier reference to -- a constant entity initialized to the appropriate value. + Last_Opnd_High_Bound : Node_Id; + -- A tree node representing the high bound of the last operand. This + -- need only be set if the result could be null. It is used for the + -- special case of setting the right high bound for a null result. + -- This is of type Ityp. + High_Bound : Node_Id; -- A tree node representing the high bound of the result (of type Ityp) @@ -2274,7 +2282,7 @@ package body Exp_Ch4 is -- we analyzed and resolved the expression. Set_Parent (X, Cnode); - Analyze_And_Resolve (X, Intyp); + Analyze_And_Resolve (X); if Compile_Time_Compare (X, Type_High_Bound (Ityp), @@ -2302,7 +2310,6 @@ package body Exp_Ch4 is -- Local Declarations - Opnd : Node_Id; Opnd_Typ : Entity_Id; Ent : Entity_Id; Len : Uint; @@ -2383,9 +2390,8 @@ package body Exp_Ch4 is Fixed_Length (NN) := Uint_1; Result_May_Be_Null := False; - -- Set bounds of operand (no need to set high bound since we know - -- for sure that result won't be null, so we won't ever use - -- Opnd_High_Bound). + -- Set low bound of operand (no need to set Last_Opnd_High_Bound + -- since we know that the result cannot be null). Opnd_Low_Bound (NN) := Make_Attribute_Reference (Loc, @@ -2399,7 +2405,21 @@ package body Exp_Ch4 is elsif Nkind (Opnd) = N_String_Literal then Len := String_Literal_Length (Opnd_Typ); - -- Skip null string literal unless last operand + if Len /= 0 then + Result_May_Be_Null := False; + end if; + + -- Capture last operand high bound if result could be null + + if J = N and then Result_May_Be_Null then + Last_Opnd_High_Bound := + Make_Op_Add (Loc, + Left_Opnd => + New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)), + Right_Opnd => Make_Integer_Literal (Loc, 1)); + end if; + + -- Skip null string literal if J < N and then Len = 0 then goto Continue; @@ -2416,14 +2436,7 @@ package body Exp_Ch4 is Opnd_Low_Bound (NN) := New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)); - Opnd_High_Bound (NN) := - Make_Op_Add (Loc, - Left_Opnd => - New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)), - Right_Opnd => Make_Integer_Literal (Loc, 1)); - Set := True; - Result_May_Be_Null := False; -- All other cases @@ -2456,10 +2469,18 @@ package body Exp_Ch4 is Result_May_Be_Null := False; end if; - -- Exclude null length case except for last operand - -- (where we may need it to get proper bounds). + -- Capture last operand bound if result could be null + + if J = N and then Result_May_Be_Null then + Last_Opnd_High_Bound := + Convert_To (Ityp, + Make_Integer_Literal (Loc, + Intval => Expr_Value (Hi))); + end if; + + -- Exclude null length case unless last operand - if Len = 0 and then J < N then + if J < N and then Len = 0 then goto Continue; end if; @@ -2472,10 +2493,6 @@ package body Exp_Ch4 is Make_Integer_Literal (Loc, Intval => Expr_Value (Lo))); - Opnd_High_Bound (NN) := To_Ityp ( - Make_Integer_Literal (Loc, - Intval => Expr_Value (Hi))); - Set := True; end; end if; @@ -2497,11 +2514,14 @@ package body Exp_Ch4 is Duplicate_Subexpr (Opnd, Name_Req => True), Attribute_Name => Name_First); - Opnd_High_Bound (NN) := - Make_Attribute_Reference (Loc, - Prefix => - Duplicate_Subexpr (Opnd, Name_Req => True), - Attribute_Name => Name_Last); + if J = N and Result_May_Be_Null then + Last_Opnd_High_Bound := + Convert_To (Ityp, + Make_Attribute_Reference (Loc, + Prefix => + Duplicate_Subexpr (Opnd, Name_Req => True), + Attribute_Name => Name_Last)); + end if; -- Capture length of operand in entity @@ -2593,14 +2613,10 @@ package body Exp_Ch4 is J := J + 1; end loop; - -- If we have only skipped null operands, return a null string literal. - -- Note that this means the lower bound is 1 and the type is string, - -- since we retained any null operands with a type other than string, - -- or a lower bound other than one, so this is a legitimate assumption. + -- If we have only skipped null operands, return the last operand if NN = 0 then - Start_String; - Result := Make_String_Literal (Loc, Strval => End_String); + Result := Opnd; goto Done; end if; @@ -2703,10 +2719,7 @@ package body Exp_Ch4 is end; end if; - -- Now find the upper bound. This is normally the Low_Bound + Length - 1 - -- but there is one exception, namely when the result is null in which - -- case the bounds come from the last operand (so that we get the proper - -- bounds if the last operand is super-flat). + -- Now find the upper bound, normally this is Low_Bound + Length - 1 High_Bound := To_Ityp ( @@ -2717,6 +2730,10 @@ package body Exp_Ch4 is Left_Opnd => New_Copy (Aggr_Length (NN)), Right_Opnd => Make_Integer_Literal (Loc, 1)))); + -- But there is one exception, namely when the result is null in which + -- case the bounds come from the last operand (so that we get the proper + -- bounds if the last operand is super-flat). + if Result_May_Be_Null then High_Bound := Make_Conditional_Expression (Loc, @@ -2724,7 +2741,7 @@ package body Exp_Ch4 is Make_Op_Eq (Loc, Left_Opnd => New_Copy (Aggr_Length (NN)), Right_Opnd => Make_Integer_Literal (Loc, 0)), - Opnd_High_Bound (NN), + Last_Opnd_High_Bound, High_Bound)); end if; |