277 log.
debug() <<
"Skip class " <<
c.name <<
" (already loaded)"
283 if(
c.signature.has_value() &&
c.signature.value()[0]==
'<')
287 std::cout <<
"INFO: found generic class signature "
288 <<
c.signature.value()
289 <<
" in parsed class "
296 c.signature.value());
297 for(
const typet &t : generic_types)
307 <<
"\n could not parse signature: " <<
c.signature.value()
322 class_type.set_is_anonymous_class(
c.is_anonymous_class);
330 <<
" won't work properly because max "
332 <<
") is less than the "
337 std::to_string(
c.enum_elements+1));
343 else if(
c.is_protected)
345 else if(
c.is_private)
350 if(!
c.super_class.empty())
370 log.
debug() <<
"Superclass: " <<
c.super_class
371 <<
" of class: " <<
c.name
372 <<
"\n could not parse signature: "
374 <<
"\n ignoring that the superclass is generic"
413 << "\n could not parse signature: " << interface_ref.value()
415 << "\n ignoring that the interface is generic"
417 class_type.add_base(base);
422 class_type.add_base(base);
427 for(const auto &lambda_entry : c.lambda_method_handle_map)
432 lambda_entry.second.is_unknown_handle()
433 ? class_type.add_unknown_lambda_method_handle()
434 : class_type.add_lambda_method_handle(
435 lambda_entry.second.get_method_descriptor(),
436 lambda_entry.second.handle_type);
440 if(!c.annotations.empty())
441 convert_annotations(c.annotations, class_type.get_annotations());
444 const irep_idt base_name = [](const std::string &full_name) {
445 const size_t last_dot = full_name.find_last_of('.');
446 return last_dot == std::string::npos
448 : std::string(full_name, last_dot + 1, std::string::npos);
449 }(id2string(c.name));
452 class_type.set_name(qualified_classname);
453 type_symbolt new_symbol{qualified_classname, class_type, ID_java};
454 new_symbol.base_name = base_name;
455 new_symbol.pretty_name=c.name;
457 symbolt *class_symbol;
460 log.debug() << "Adding symbol: class '" << c.name << "'" << messaget::eom;
461 if(symbol_table.move(new_symbol, class_symbol))
463 log.error() << "failed to add class symbol " << new_symbol.name
469 const class_typet::componentst &fields =
470 to_class_type(class_symbol->type).components();
473 for(auto overlay_class : overlay_classes)
475 for(const auto &field : overlay_class.get().fields)
477 std::string field_id = qualified_classname + "." + id2string(field.name);
478 if(check_field_exists(field, field_id, fields))
481 "Duplicate field definition for " + field_id + " in overlay class";
483 log.error() << err << messaget::eom;
486 log.debug() << "Adding symbol from overlay class: field '" << field.name
487 << "'" << messaget::eom;
488 convert(*class_symbol, field);
489 POSTCONDITION(check_field_exists(field, field_id, fields));
492 for(const auto &field : c.fields)
494 std::string field_id = qualified_classname + "." + id2string(field.name);
495 if(check_field_exists(field, field_id, fields))
498 log.error() << "Field definition for " << field_id
499 << " already loaded from overlay class" << messaget::eom;
502 log.debug() << "Adding symbol: field '" << field.name << "'"
504 convert(*class_symbol, field);
505 POSTCONDITION(check_field_exists(field, field_id, fields));
509 std::set<irep_idt> overlay_methods;
510 for(auto overlay_class : overlay_classes)
512 for(const methodt &method : overlay_class.get().methods)
514 const irep_idt method_identifier =
515 qualified_classname + "." + id2string(method.name)
516 + ":" + method.descriptor;
517 if(is_ignored_method(c.name, method))
519 log.debug() << "Ignoring method: '" << method_identifier << "'"
523 if(method_bytecode.contains_method(method_identifier))
530 if(overlay_methods.count(method_identifier) == 0)
535 << "Method " << method_identifier
536 << " exists in an overlay class without being marked as an "
537 "overlay and also exists in another overlay class that appears "
538 "earlier in the classpath"
545 log.debug() << "Adding symbol from overlay class: method '"
546 << method_identifier << "'" << messaget::eom;
547 java_bytecode_convert_method_lazy(
552 log.get_message_handler());
553 method_bytecode.add(qualified_classname, method_identifier, method);
554 if(is_overlay_method(method))
555 overlay_methods.insert(method_identifier);
558 for(const methodt &method : c.methods)
560 const irep_idt method_identifier=
561 qualified_classname + "." + id2string(method.name)
562 + ":" + method.descriptor;
563 if(is_ignored_method(c.name, method))
565 log.debug() << "Ignoring method: '" << method_identifier << "'"
569 if(method_bytecode.contains_method(method_identifier))
575 if(overlay_methods.erase(method_identifier) == 0)
580 << "Method " << method_identifier
581 << " exists in an overlay class without being marked as an overlay "
582 "and also exists in the underlying class"
589 log.debug() << "Adding symbol: method '" << method_identifier << "'"
591 java_bytecode_convert_method_lazy(
596 log.get_message_handler());
597 method_bytecode.add(qualified_classname, method_identifier, method);
598 if(is_overlay_method(method))
601 << "Method " << method_identifier
602 << " marked as an overlay where defined in the underlying class"
606 if(!overlay_methods.empty())
609 << "Overlay methods defined in overlay classes did not exist in the "
610 "underlying class:\n";
611 for(const irep_idt &method_id : overlay_methods)
612 log.error() << " " << method_id << "\n";
613 log.error() << messaget::eom;
617 if(c.super_class.empty())
618 java_root_class(*class_symbol);
642void java_bytecode_convert_classt::convert(
643 symbolt &class_symbol,
647 if(f.signature.has_value())
649 field_type = *java_type_from_string_with_exception(
650 f.descriptor, f.signature, id2string(class_symbol.name));
653 if(is_java_generic_parameter(field_type))
656 std::cout << "fieldtype: generic "
657 << to_java_generic_parameter(field_type).type_variable()
659 << " name " << f.name << "\n";
665 else if(is_java_generic_type(field_type))
667 java_generic_typet &with_gen_type=
668 to_java_generic_type(field_type);
670 std::cout << "fieldtype: generic container type "
671 << std::to_string(with_gen_type.generic_type_arguments().size())
672 << " type " << with_gen_type.id()
673 << " name " << f.name
674 << " subtype id " << with_gen_type.subtype().id() << "\n";
676 field_type=with_gen_type;
680 field_type = *java_type_from_string(f.descriptor);
687 else if(f.is_protected)
688 access = ID_protected;
694 auto &class_type = to_java_class_type(class_symbol.type);
699 const irep_idt field_identifier =
700 id2string(class_symbol.name) + "." + id2string(f.name);
702 class_type.static_members().emplace_back();
703 auto &component = class_type.static_members().back();
705 component.set_name(field_identifier);
706 component.set_base_name(f.name);
707 component.set_pretty_name(f.name);
708 component.set_access(access);
709 component.set_is_final(f.is_final);
710 component.type() = field_type;
714 id2string(class_symbol.name) + "." + id2string(f.name),
718 new_symbol.is_static_lifetime=true;
719 new_symbol.is_lvalue=true;
720 new_symbol.is_state_var=true;
721 new_symbol.base_name=f.name;
724 set_declaring_class(new_symbol, class_symbol.name);
725 new_symbol.type.set(ID_C_field, f.name);
726 new_symbol.type.set(ID_C_constant, f.is_final);
727 new_symbol.pretty_name=id2string(class_symbol.pretty_name)+
728 "."+id2string(f.name);
735 new_symbol.type.set(ID_C_access, ID_public);
736 else if(f.is_protected)
737 new_symbol.type.set(ID_C_access, ID_protected);
738 else if(f.is_private)
739 new_symbol.type.set(ID_C_access, ID_private);
741 new_symbol.type.set(ID_C_access, ID_default);
743 const namespacet ns(symbol_table);
744 const auto value = zero_initializer(field_type, class_symbol.location, ns);
745 if(!value.has_value())
747 log.error().source_location = class_symbol.location;
748 log.error() << "failed to zero-initialize " << f.name << messaget::eom;
751 new_symbol.value = *value;
754 if(!f.annotations.empty())
758 type_checked_cast<annotated_typet>(new_symbol.type).get_annotations());
762 const auto s_it=symbol_table.symbols.find(new_symbol.name);
763 if(s_it!=symbol_table.symbols.end())
764 symbol_table.erase(s_it);
766 const bool failed = symbol_table.add(new_symbol);
767 CHECK_RETURN_WITH_DIAGNOSTICS(!failed, "failed to add static field symbol");
771 class_type.components().emplace_back();
772 auto &component = class_type.components().back();
774 component.set_name(f.name);
775 component.set_base_name(f.name);
776 component.set_pretty_name(f.name);
777 component.set_access(access);
778 component.set_is_final(f.is_final);
779 component.type() = field_type;
782 if(!f.annotations.empty())
786 static_cast<annotated_typet &>(component.type()).get_annotations());
791void add_java_array_types(symbol_table_baset &symbol_table)
793 const std::string letters="ijsbcfdza";
795 for(const char l : letters)
797 struct_tag_typet struct_tag_type =
798 to_struct_tag_type(java_array_type(l).subtype());
800 const irep_idt &struct_tag_type_identifier =
801 struct_tag_type.get_identifier();
802 if(symbol_table.has_symbol(struct_tag_type_identifier))
805 java_class_typet class_type;
808 class_type.set_tag(struct_tag_type_identifier);
813 class_type.set_name(struct_tag_type_identifier);
815 class_type.components().reserve(3);
816 java_class_typet::componentt base_class_component(
817 "@java.lang.Object", struct_tag_typet("java::java.lang.Object"));
818 base_class_component.set_pretty_name("@java.lang.Object");
819 base_class_component.set_base_name("@java.lang.Object");
820 class_type.components().push_back(base_class_component);
822 java_class_typet::componentt length_component("length", java_int_type());
823 length_component.set_pretty_name("length");
824 length_component.set_base_name("length");
825 class_type.components().push_back(length_component);
827 java_class_typet::componentt data_component(
828 "data", java_reference_type(java_type_from_char(l)));
829 data_component.set_pretty_name("data");
830 data_component.set_base_name("data");
831 class_type.components().push_back(data_component);
837 java_class_typet::componentt array_element_classid_component(
838 JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME, string_typet());
839 array_element_classid_component.set_pretty_name(
840 JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
841 array_element_classid_component.set_base_name(
842 JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
843 class_type.components().push_back(array_element_classid_component);
845 java_class_typet::componentt array_dimension_component(
846 JAVA_ARRAY_DIMENSION_FIELD_NAME, java_int_type());
847 array_dimension_component.set_pretty_name(
848 JAVA_ARRAY_DIMENSION_FIELD_NAME);
849 array_dimension_component.set_base_name(JAVA_ARRAY_DIMENSION_FIELD_NAME);
850 class_type.components().push_back(array_dimension_component);
853 class_type.add_base(struct_tag_typet("java::java.lang.Object"));
856 is_valid_java_array(class_type),
857 "Constructed a new type representing a Java Array "
858 "object that doesn't match expectations");
860 type_symbolt symbol{struct_tag_type_identifier, class_type, ID_java};
861 symbol.base_name = struct_tag_type.get(ID_C_base_name);
862 symbol_table.add(symbol);
867 const irep_idt clone_name =
868 id2string(struct_tag_type_identifier) + ".clone:()Ljava/lang/Object;";
869 java_method_typet::parametert this_param(
870 java_reference_type(struct_tag_type));
871 this_param.set_identifier(id2string(clone_name)+"::this");
872 this_param.set_base_name(ID_this);
873 this_param.set_this();
874 const java_method_typet clone_type({this_param}, java_lang_object_type());
876 parameter_symbolt this_symbol;
877 this_symbol.name=this_param.get_identifier();
878 this_symbol.base_name=this_param.get_base_name();
879 this_symbol.pretty_name=this_symbol.base_name;
880 this_symbol.type=this_param.type();
881 this_symbol.mode=ID_java;
882 symbol_table.add(this_symbol);
884 const irep_idt local_name=
885 id2string(clone_name)+"::cloned_array";
886 auxiliary_symbolt local_symbol;
887 local_symbol.name=local_name;
888 local_symbol.base_name="cloned_array";
889 local_symbol.pretty_name=local_symbol.base_name;
890 local_symbol.type = java_reference_type(struct_tag_type);
891 local_symbol.mode=ID_java;
892 symbol_table.add(local_symbol);
893 const auto local_symexpr = local_symbol.symbol_expr();
895 code_declt declare_cloned(local_symexpr);
897 source_locationt location;
898 location.set_function(local_name);
899 side_effect_exprt java_new_array(
900 ID_java_new_array, java_reference_type(struct_tag_type), location);
901 dereference_exprt old_array{this_symbol.symbol_expr()};
902 dereference_exprt new_array{local_symexpr};
903 member_exprt old_length(
904 old_array, length_component.get_name(), length_component.type());
905 java_new_array.copy_to_operands(old_length);
906 code_frontend_assignt create_blank(local_symexpr, java_new_array);
908 codet copy_type_information = code_skipt();
913 const auto &array_dimension_component =
914 class_type.get_component(JAVA_ARRAY_DIMENSION_FIELD_NAME);
915 const auto &array_element_classid_component =
916 class_type.get_component(JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
918 member_exprt old_array_dimension(old_array, array_dimension_component);
919 member_exprt old_array_element_classid(
920 old_array, array_element_classid_component);
922 member_exprt new_array_dimension(new_array, array_dimension_component);
923 member_exprt new_array_element_classid(
924 new_array, array_element_classid_component);
926 copy_type_information = code_blockt{
927 {code_frontend_assignt(new_array_dimension, old_array_dimension),
928 code_frontend_assignt(
929 new_array_element_classid, old_array_element_classid)}};
932 member_exprt old_data(
933 old_array, data_component.get_name(), data_component.type());
934 member_exprt new_data(
935 new_array, data_component.get_name(), data_component.type());
947 const irep_idt index_name=
948 id2string(clone_name)+"::index";
949 auxiliary_symbolt index_symbol;
950 index_symbol.name=index_name;
951 index_symbol.base_name="index";
952 index_symbol.pretty_name=index_symbol.base_name;
953 index_symbol.type = length_component.type();
954 index_symbol.mode=ID_java;
955 symbol_table.add(index_symbol);
956 const auto &index_symexpr=index_symbol.symbol_expr();
958 code_declt declare_index(index_symexpr);
960 dereference_exprt old_cell(
961 plus_exprt(old_data, index_symexpr),
962 to_type_with_subtype(old_data.type()).subtype());
963 dereference_exprt new_cell(
964 plus_exprt(new_data, index_symexpr),
965 to_type_with_subtype(new_data.type()).subtype());
967 const code_fort copy_loop = code_fort::from_index_bounds(
968 from_integer(0, index_symexpr.type()),
971 code_frontend_assignt(std::move(new_cell), std::move(old_cell)),
974 member_exprt new_base_class(
975 new_array, base_class_component.get_name(), base_class_component.type());
976 address_of_exprt retval(new_base_class);
977 code_returnt return_inst(retval);
979 const code_blockt clone_body({declare_cloned,
981 copy_type_information,
986 symbolt clone_symbol{clone_name, clone_type, ID_java};
987 clone_symbol.pretty_name =
988 id2string(struct_tag_type_identifier) + ".clone:()";
989 clone_symbol.base_name="clone";
990 clone_symbol.value=clone_body;
991 symbol_table.add(clone_symbol);
1180void mark_java_implicitly_generic_class_type(
1181 const irep_idt &class_name,
1182 symbol_table_baset &symbol_table)
1184 const std::string qualified_class_name = "java::" + id2string(class_name);
1185 PRECONDITION(symbol_table.has_symbol(qualified_class_name));
1187 symbolt &class_symbol = symbol_table.get_writeable_ref(qualified_class_name);
1188 const java_class_typet &class_type = to_java_class_type(class_symbol.type);
1193 bool no_this_field = std::none_of(
1194 class_type.components().begin(),
1195 class_type.components().end(),
1196 [](const struct_union_typet::componentt &component)
1198 return id2string(component.get_name()).substr(0, 5) == "this$";
1207 std::vector<java_generic_parametert> implicit_generic_type_parameters;
1208 std::string::size_type outer_class_delimiter =
1209 qualified_class_name.rfind('$');
1210 while(outer_class_delimiter != std::string::npos)
1212 std::string outer_class_name =
1213 qualified_class_name.substr(0, outer_class_delimiter);
1214 if(symbol_table.has_symbol(outer_class_name))
1216 const symbolt &outer_class_symbol =
1217 symbol_table.lookup_ref(outer_class_name);
1218 const java_class_typet &outer_class_type =
1219 to_java_class_type(outer_class_symbol.type);
1220 if(is_java_generic_class_type(outer_class_type))
1222 for(const java_generic_parametert &outer_generic_type_parameter :
1223 to_java_generic_class_type(outer_class_type).generic_types())
1227 irep_idt identifier = qualified_class_name + "::" +
1228 id2string(strip_java_namespace_prefix(
1229 outer_generic_type_parameter.get_name()));
1230 java_generic_parameter_tagt bound = to_java_generic_parameter_tag(
1231 outer_generic_type_parameter.base_type());
1232 bound.type_variable_ref().set_identifier(identifier);
1233 implicit_generic_type_parameters.emplace_back(identifier, bound);
1236 outer_class_delimiter = outer_class_name.rfind('$');
1240 throw missing_outer_class_symbol_exceptiont(
1241 outer_class_name, qualified_class_name);
1247 if(!implicit_generic_type_parameters.empty())
1249 java_implicitly_generic_class_typet new_class_type(
1250 class_type, implicit_generic_type_parameters);
1253 if(is_java_generic_class_type(class_type))
1255 const java_generic_class_typet::generic_typest &class_type_params =
1256 to_java_generic_class_type(class_type).generic_types();
1257 implicit_generic_type_parameters.insert(
1258 implicit_generic_type_parameters.begin(),
1259 class_type_params.begin(),
1260 class_type_params.end());
1263 for(auto &field : new_class_type.components())
1265 find_and_replace_parameters(
1266 field.type(), implicit_generic_type_parameters);
1269 for(auto &base : new_class_type.bases())
1271 find_and_replace_parameters(
1272 base.type(), implicit_generic_type_parameters);
1275 class_symbol.type = new_class_type;