@@ -20,6 +20,7 @@ Date: April 2017
20
20
#include < util/allocate_objects.h>
21
21
#include < util/arith_tools.h>
22
22
#include < util/c_types.h>
23
+ #include < util/expr_initializer.h>
23
24
#include < util/fresh_symbol.h>
24
25
#include < util/refined_string_type.h>
25
26
#include < util/std_code.h>
@@ -188,6 +189,17 @@ java_string_library_preprocesst::get_string_type_base_classes(
188
189
189
190
std::vector<irep_idt> bases;
190
191
bases.reserve (3 );
192
+
193
+ // StringBuilder and StringBuffer derive from AbstractStringBuilder;
194
+ // other String types (String and CharSequence) derive directly from Object.
195
+ if (
196
+ class_name == " java.lang.StringBuilder" ||
197
+ class_name == " java.lang.StringBuffer" )
198
+ bases.push_back (" java.lang.AbstractStringBuilder" );
199
+ else
200
+ bases.push_back (" java.lang.Object" );
201
+
202
+ // Interfaces:
191
203
if (class_name != " java.lang.CharSequence" )
192
204
{
193
205
bases.push_back (" java.io.Serializable" );
@@ -196,10 +208,6 @@ java_string_library_preprocesst::get_string_type_base_classes(
196
208
if (class_name == " java.lang.String" )
197
209
bases.push_back (" java.lang.Comparable" );
198
210
199
- if (class_name == " java.lang.StringBuilder" ||
200
- class_name == " java.lang.StringBuffer" )
201
- bases.push_back (" java.lang.AbstractStringBuilder" );
202
-
203
211
return bases;
204
212
}
205
213
@@ -209,36 +217,55 @@ java_string_library_preprocesst::get_string_type_base_classes(
209
217
void java_string_library_preprocesst::add_string_type (
210
218
const irep_idt &class_name, symbol_tablet &symbol_table)
211
219
{
212
- java_class_typet string_type;
213
- string_type.set_tag (class_name);
214
- string_type.set_name (" java::" + id2string (class_name));
220
+ irep_idt class_symbol_name = " java::" + id2string (class_name);
221
+ symbolt tmp_string_symbol;
222
+ tmp_string_symbol.name = class_symbol_name;
223
+ symbolt *string_symbol = nullptr ;
224
+ bool already_exists = symbol_table.move (tmp_string_symbol, string_symbol);
225
+
226
+ if (already_exists)
227
+ {
228
+ // A library has already defined this type -- we'll replace its
229
+ // components with those required for internal string modelling, but
230
+ // otherwise leave it alone.
231
+ to_java_class_type (string_symbol->type ).components ().clear ();
232
+ }
233
+ else
234
+ {
235
+ // No definition of this type exists -- define it as it usually occurs in
236
+ // the JDK:
237
+ java_class_typet new_string_type;
238
+ new_string_type.set_tag (class_name);
239
+ new_string_type.set_name (class_symbol_name);
240
+ new_string_type.set_access (ID_public);
241
+
242
+ std::vector<irep_idt> bases = get_string_type_base_classes (class_name);
243
+ for (const irep_idt &base_name : bases)
244
+ new_string_type.add_base (
245
+ struct_tag_typet (" java::" + id2string (base_name)));
246
+
247
+ string_symbol->base_name = id2string (class_name);
248
+ string_symbol->pretty_name = id2string (class_name);
249
+ string_symbol->type = new_string_type;
250
+ string_symbol->is_type = true ;
251
+ string_symbol->mode = ID_java;
252
+ }
253
+
254
+ auto &string_type = to_java_class_type (string_symbol->type );
255
+
215
256
string_type.components ().resize (3 );
216
- string_type.components ()[0 ].set_name (" @java.lang.Object" );
217
- string_type.components ()[0 ].set_pretty_name (" @java.lang.Object" );
218
- string_type.components ()[0 ].type () =
219
- struct_tag_typet (" java::java.lang.Object" );
257
+ const struct_tag_typet &supertype = string_type.bases ().front ().type ();
258
+ irep_idt supertype_component_name =
259
+ " @" + id2string (supertype.get_identifier ()).substr (6 );
260
+ string_type.components ()[0 ].set_name (supertype_component_name);
261
+ string_type.components ()[0 ].set_pretty_name (supertype_component_name);
262
+ string_type.components ()[0 ].type () = supertype;
220
263
string_type.components ()[1 ].set_name (" length" );
221
264
string_type.components ()[1 ].set_pretty_name (" length" );
222
265
string_type.components ()[1 ].type ()=string_length_type ();
223
266
string_type.components ()[2 ].set_name (" data" );
224
267
string_type.components ()[2 ].set_pretty_name (" data" );
225
268
string_type.components ()[2 ].type () = pointer_type (java_char_type ());
226
- string_type.set_access (ID_public);
227
- string_type.add_base (struct_tag_typet (" java::java.lang.Object" ));
228
-
229
- std::vector<irep_idt> bases = get_string_type_base_classes (class_name);
230
- for (const irep_idt &base_name : bases)
231
- string_type.add_base (struct_tag_typet (" java::" + id2string (base_name)));
232
-
233
- symbolt tmp_string_symbol;
234
- tmp_string_symbol.name =" java::" +id2string (class_name);
235
- symbolt *string_symbol=nullptr ;
236
- symbol_table.move (tmp_string_symbol, string_symbol);
237
- string_symbol->base_name =id2string (class_name);
238
- string_symbol->pretty_name =id2string (class_name);
239
- string_symbol->type =string_type;
240
- string_symbol->is_type =true ;
241
- string_symbol->mode = ID_java;
242
269
}
243
270
244
271
// / calls string_refine_preprocesst::process_operands with a list of parameters.
@@ -776,14 +803,15 @@ codet java_string_library_preprocesst::code_assign_components_to_java_string(
776
803
777
804
if (is_constructor)
778
805
{
779
- // A String has a field Object with @clsid = String
780
- struct_tag_typet jlo_tag (" java::java.lang.Object" );
781
- struct_exprt jlo_init ({}, jlo_tag);
782
- irep_idt clsid = get_tag (lhs.type ().subtype ());
806
+ // Initialise the supertype with the appropriate classid:
783
807
namespacet ns (symbol_table);
784
- java_root_class_init (jlo_init, ns.follow_tag (jlo_tag), clsid);
785
-
786
- struct_exprt struct_rhs ({jlo_init, rhs_length, rhs_array}, deref.type ());
808
+ const struct_typet &lhs_type = to_struct_type (ns.follow (deref.type ()));
809
+ auto zero_base_object = *zero_initializer (
810
+ lhs_type.components ().front ().type (), source_locationt{}, ns);
811
+ set_class_identifier (
812
+ to_struct_expr (zero_base_object), ns, to_struct_tag_type (deref.type ()));
813
+ struct_exprt struct_rhs (
814
+ {zero_base_object, rhs_length, rhs_array}, deref.type ());
787
815
return code_assignt (checked_dereference (lhs), struct_rhs);
788
816
}
789
817
else
0 commit comments