aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/stringt.adb
diff options
context:
space:
mode:
authorBob Duff <duff@adacore.com>2007-08-31 12:23:37 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2007-08-31 12:23:37 +0200
commitb54ddf5adfaa5be8c910c862d62b3726670df773 (patch)
tree198081394ea01406fbc6cf4d9510dc38574a8add /gcc/ada/stringt.adb
parentb90cfacd5f804816323d230bd3d7fc4d62569d5b (diff)
downloadgcc-b54ddf5adfaa5be8c910c862d62b3726670df773.zip
gcc-b54ddf5adfaa5be8c910c862d62b3726670df773.tar.gz
gcc-b54ddf5adfaa5be8c910c862d62b3726670df773.tar.bz2
par-ch4.adb (P_Simple_Expression): Fold long sequences of concatenations of string literals into a single literal...
2007-08-31 Bob Duff <duff@adacore.com> * par-ch4.adb (P_Simple_Expression): Fold long sequences of concatenations of string literals into a single literal, in order to avoid very deep recursion in the front end, which was causing stack overflow. * sem_eval.adb (Eval_Concatenation): If the left operand is the empty string, and the right operand is a string literal (the case of "" & "..."), optimize by avoiding copying the right operand -- just use the value of the right operand directly. * stringt.adb (Store_String_Chars): Optimize by growing the String_Chars table all at once, rather than appending characters one by one. (Write_String_Table_Entry): If the string to be printed is very long, just print the first few characters, followed by the length. Otherwise, doing "pn(n)" in the debugger can take an extremely long time. * sem_prag.adb (Process_Interface_Name): Replace loop doing Store_String_Char with Store_String_Chars. From-SVN: r127977
Diffstat (limited to 'gcc/ada/stringt.adb')
-rw-r--r--gcc/ada/stringt.adb32
1 files changed, 29 insertions, 3 deletions
diff --git a/gcc/ada/stringt.adb b/gcc/ada/stringt.adb
index e272009..88b72e05 100644
--- a/gcc/ada/stringt.adb
+++ b/gcc/ada/stringt.adb
@@ -202,10 +202,27 @@ package body Stringt is
end Store_String_Chars;
procedure Store_String_Chars (S : String_Id) is
+
+ -- We are essentially doing this:
+
+ -- for J in 1 .. String_Length (S) loop
+ -- Store_String_Char (Get_String_Char (S, J));
+ -- end loop;
+
+ -- but when the string is long it's more efficient to grow the
+ -- String_Chars table all at once.
+
+ S_First : constant Int := Strings.Table (S).String_Index;
+ S_Len : constant Int := String_Length (S);
+ Old_Last : constant Int := String_Chars.Last;
+ New_Last : constant Int := Old_Last + S_Len;
+
begin
- for J in 1 .. String_Length (S) loop
- Store_String_Char (Get_String_Char (S, J));
- end loop;
+ String_Chars.Set_Last (New_Last);
+ String_Chars.Table (Old_Last + 1 .. New_Last) :=
+ String_Chars.Table (S_First .. S_First + S_Len - 1);
+ Strings.Table (Strings.Last).Length :=
+ Strings.Table (Strings.Last).Length + S_Len;
end Store_String_Chars;
----------------------
@@ -417,6 +434,15 @@ package body Stringt is
else
Write_Char_Code (C);
end if;
+
+ -- If string is very long, quit
+
+ if J >= 1000 then -- arbitrary limit
+ Write_Str ("""...etc (length = ");
+ Write_Int (String_Length (Id));
+ Write_Str (")");
+ return;
+ end if;
end loop;
Write_Char ('"');