25 #include <unordered_set>
38 static std::unordered_map<irep_idt, java_boxed_type_infot> type_info_by_name =
40 {
"java::java.lang.Boolean",
42 {
"java::java.lang.Byte",
44 {
"java::java.lang.Character",
46 {
"java::java.lang.Double",
48 {
"java::java.lang.Float",
50 {
"java::java.lang.Integer",
52 {
"java::java.lang.Long",
54 {
"java::java.lang.Short",
58 auto found = type_info_by_name.
find(type_name);
59 return found == type_info_by_name.end() ? nullptr : &found->second;
65 static std::unordered_map<typet, java_primitive_type_infot, irep_hash>
66 type_info_by_primitive_type = {
68 {
"java::java.lang.Boolean",
69 "java::java.lang.Boolean.valueOf:(Z)Ljava/lang/Boolean;",
70 "java::java.lang.Boolean.booleanValue:()Z"}},
72 {
"java::java.lang.Byte",
73 "java::java.lang.Byte.valueOf:(B)Ljava/lang/Byte;",
74 "java::java.lang.Number.byteValue:()B"}},
76 {
"java::java.lang.Character",
77 "java::java.lang.Character.valueOf:(C)"
78 "Ljava/lang/Character;",
79 "java::java.lang.Character.charValue:()C"}},
81 {
"java::java.lang.Double",
82 "java::java.lang.Double.valueOf:(D)"
84 "java::java.lang.Number.doubleValue:()D"}},
86 {
"java::java.lang.Float",
87 "java::java.lang.Float.valueOf:(F)"
89 "java::java.lang.Number.floatValue:()F"}},
91 {
"java::java.lang.Integer",
92 "java::java.lang.Integer.valueOf:(I)"
93 "Ljava/lang/Integer;",
94 "java::java.lang.Number.intValue:()I"}},
96 {
"java::java.lang.Long",
97 "java::java.lang.Long.valueOf:(J)Ljava/lang/Long;",
98 "java::java.lang.Number.longValue:()J"}},
100 {
"java::java.lang.Short",
101 "java::java.lang.Short.valueOf:(S)"
103 "java::java.lang.Number.shortValue:()S"}}};
105 auto found = type_info_by_primitive_type.
find(maybe_primitive_type);
106 return found == type_info_by_primitive_type.end() ? nullptr : &found->second;
116 static const std::unordered_set<std::string> primitive_wrapper_type_names = {
119 "java.lang.Character",
125 return primitive_wrapper_type_names.count(type_name) > 0;
132 if(t.
id()==ID_pointer)
141 "all types constructed in java_types.cpp encode JVM types "
142 "with these bit widths");
144 return bitwidth == 64 ? 2u : 1u;
170 class_type.
set_tag(class_name);
175 class_type.
set_name(qualified_class_name);
176 type_symbolt new_symbol{qualified_class_name, std::move(class_type), ID_java};
177 new_symbol.base_name=class_name;
178 new_symbol.pretty_name=class_name;
180 std::pair<symbolt &, bool> res=symbol_table.
insert(std::move(new_symbol));
186 "stub class symbol " <<
213 const std::string &friendly_name,
217 std::string qualified_name=
"java::"+friendly_name;
218 if(friendly_name.rfind(
':')==std::string::npos)
220 std::string prefix=qualified_name+
':';
221 std::set<irep_idt> matches;
223 for(
const auto &s : symbol_table.
symbols)
224 if(s.first.starts_with(prefix) && s.second.type.id() == ID_code)
225 matches.insert(s.first);
229 error=
"'"+friendly_name+
"' not found";
232 else if(matches.size()>1)
234 std::ostringstream message;
235 message <<
"'"+friendly_name+
"' is ambiguous between:";
238 for(
const auto &s : matches)
239 message <<
"\n " <<
id2string(s).substr(6);
246 return *matches.begin();
251 auto findit=symbol_table.
symbols.find(qualified_name);
252 if(findit==symbol_table.
symbols.end())
254 error=
"'"+friendly_name+
"' not found";
257 else if(findit->second.type.id()!=ID_code)
259 error=
"'"+friendly_name+
"' not a function";
264 return findit->first;
285 result.
set(ID_java_member_access,
true);
303 const std::string &src,
312 size_t c_pos=open_pos+1;
313 const size_t end_pos=src.size()-1;
316 while(c_pos<=end_pos)
318 if(src[c_pos] == open_char)
320 else if(src[c_pos] == close_char)
329 depth<=(src.size()-open_pos),
331 "\' found in signature to parse.");
334 return std::string::npos;
350 components.end(), components_to_add.begin(), components_to_add.end());
368 func_symbol.
mode=ID_java;
369 func_symbol.
name=function_name;
370 func_symbol.
type=type;
371 symbol_table.
add(func_symbol);
390 std::vector<typet> argument_types;
391 for(
const auto &arg : arguments)
392 argument_types.push_back(arg.type());
409 const std::string to_strip_str=
id2string(to_strip);
410 const std::string prefix=
"java::";
413 return to_strip_str.substr(prefix.size(), std::string::npos);
423 std::string result(fqn_java_type);
424 const std::string java_cbmc_string(
"java::");
426 if(
has_prefix(fqn_java_type, java_cbmc_string))
427 result = fqn_java_type.substr(java_cbmc_string.length());
430 const std::string java_lang_string(
"java.lang.");
432 result = result.substr(java_lang_string.length());
447 std::optional<resolve_inherited_componentt::inherited_componentt>
452 bool include_interfaces)
455 const auto resolved_component =
456 component_resolver(component_class_id, component_name, include_interfaces);
462 if(resolved_component)
465 if(component_class_id == resolved_component->get_class_identifier())
466 return *resolved_component;
470 resolved_component->get_full_component_identifier());
474 access = component_symbol.
type.
get(ID_C_access);
476 if(access==ID_public || access==ID_protected)
479 return *resolved_component;
484 if(access==ID_default)
486 const std::string &class_package=
489 id2string(resolved_component->get_class_identifier()));
490 if(component_package == class_package)
491 return *resolved_component;
496 if(access==ID_private)
521 static const irep_idt in =
"java::java.lang.System.in";
522 static const irep_idt out =
"java::java.lang.System.out";
523 static const irep_idt err =
"java::java.lang.System.err";
524 return symbolid == in || symbolid == out || symbolid ==
err;
545 "getCurrentThreadId",
557 const std::string &basename_prefix,
563 const std::string name_prefix =
id2string(function_name);
565 type, name_prefix, basename_prefix, source_location, ID_java, symbol_table);
571 return class_id.
empty() ? std::optional<irep_idt>{} : class_id;
579 [[nodiscard]] std::optional<std::string>
582 const auto signature_index = method_name.rfind(
":");
583 const auto method_index = method_name.rfind(
".", signature_index);
584 if(method_index == std::string::npos)
586 return method_name.substr(0, method_index);
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
pointer_typet pointer_type(const typet &subtype)
Internally generated symbol table entryThis is a symbol generated as part of translation to or modifi...
std::size_t get_width() const
const parameterst & parameters() const
Operator to dereference a pointer.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
std::vector< exprt > operandst
source_locationt & add_source_location()
Application of (mathematical) function.
const irept & find(const irep_idt &name) const
const irep_idt & get(const irep_idt &name) const
void set(const irep_idt &name, const irep_idt &value)
const irep_idt & id() const
void set_is_stub(bool is_stub)
void set_name(const irep_idt &name)
Set the name of the struct, which can be used to look up its symbol in the symbol table.
const irep_idt & get_name() const
Get the name of the struct, which can be used to look up its symbol in the symbol table.
static bool implements_java_char_sequence(const typet &type)
A type for mathematical functions (do not confuse with functions/methods in code)
Class that provides messages with a built-in verbosity 'level'.
mstreamt & warning() const
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
void merge(const source_locationt &from)
Set all unset source-location fields in this object to their values in 'from'.
A struct tag type, i.e., struct_typet with an identifier.
Structure type, corresponds to C style structs.
void set_tag(const irep_idt &tag)
bool has_component(const irep_idt &component_name) const
const componentst & components() const
std::vector< componentt > componentst
The symbol table base class interface.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
irep_idt base_name
Base (non-scoped) name.
typet type
Type of symbol.
irep_idt name
The unique identifier.
irep_idt pretty_name
Language-specific display name.
irep_idt mode
Language mode.
Symbol table entry describing a data typeThis is a symbol generated as part of type checking.
The type of an expression, extends irept.
bool has_prefix(const std::string &s, const std::string &prefix)
void err(int eval, const char *fmt,...)
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Fresh auxiliary symbol creation.
const std::string & id2string(const irep_idt &d)
void java_root_class(symbolt &class_symbol)
Create components to an object of the root class (usually java.lang.Object) Specifically,...
Produce code for simple implementation of String Java libraries.
signedbv_typet java_int_type()
signedbv_typet java_byte_type()
signedbv_typet java_short_type()
floatbv_typet java_double_type()
floatbv_typet java_float_type()
c_bool_typet java_boolean_type()
unsignedbv_typet java_char_type()
signedbv_typet java_long_type()
bool is_primitive_wrapper_type_name(const std::string &type_name)
Returns true iff the argument is the fully qualified name of a Java primitive wrapper type (for examp...
bool is_java_string_literal_id(const irep_idt &id)
const java_primitive_type_infot * get_java_primitive_type_info(const typet &maybe_primitive_type)
If primitive_type is a Java primitive type, return information about it, otherwise return null.
const java_boxed_type_infot * get_boxed_type_info_by_name(const irep_idt &type_name)
If type_name is a Java boxed type tag, return information about it, otherwise return null.
void java_add_components_to_class(symbolt &class_symbol, const struct_union_typet::componentst &components_to_add)
Add the components in components_to_add to the class denoted by class symbol.
const std::unordered_set< std::string > cprover_methods_to_ignore
Methods belonging to the class org.cprover.CProver that should be ignored (not converted),...
std::optional< irep_idt > declaring_class(const symbolt &symbol)
Gets the identifier of the class which declared a given symbol.
bool is_non_null_library_global(const irep_idt &symbolid)
Check if a symbol is a well-known non-null global.
symbolt & fresh_java_symbol(const typet &type, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &function_name, symbol_table_baset &symbol_table)
irep_idt resolve_friendly_method_name(const std::string &friendly_name, const symbol_table_baset &symbol_table, std::string &error)
Resolves a user-friendly method name (like packagename.Class.method) into an internal name (like java...
static auxiliary_symbolt declare_function(const irep_idt &function_name, const mathematical_function_typet &type, symbol_table_baset &symbol_table)
Declare a function with the given name and type.
void set_declaring_class(symbolt &symbol, const irep_idt &declaring_class)
Sets the identifier of the class which declared a given symbol to declaring_class.
bool is_primitive_wrapper_type_id(const irep_idt &id)
Returns true iff the argument is the symbol-table identifier of a Java primitive wrapper type (for ex...
void generate_class_stub(const irep_idt &class_name, symbol_table_baset &symbol_table, message_handlert &message_handler, const struct_union_typet::componentst &componentst)
bool is_java_string_type(const struct_typet &struct_type)
Returns true iff the argument represents a string type (CharSequence, StringBuilder,...
unsigned java_method_parameter_slots(const java_method_typet &t)
Returns the the number of JVM local variables (slots) used by the JVM to pass, upon call,...
size_t find_closing_delimiter(const std::string &src, size_t open_pos, char open_char, char close_char)
Finds the corresponding closing delimiter to the given opening delimiter.
irep_idt strip_java_namespace_prefix(const irep_idt &to_strip)
Strip java:: prefix from given identifier.
dereference_exprt checked_dereference(const exprt &expr)
Dereference an expression and flag it for a null-pointer check.
exprt make_function_application(const irep_idt &function_name, const exprt::operandst &arguments, const typet &range, symbol_table_baset &symbol_table)
Create a (mathematical) function application expression.
pointer_typet pointer_to_replacement_type(const pointer_typet &given_pointer_type, const java_class_typet &replacement_class_type)
Given a pointer type to a Java class and a type representing a more specific Java class,...
unsigned java_local_variable_slots(const typet &t)
Returns the number of JVM local variables (slots) taken by a local variable that, when translated to ...
std::optional< resolve_inherited_componentt::inherited_componentt > get_inherited_component(const irep_idt &component_class_id, const irep_idt &component_name, const symbol_table_baset &symbol_table, bool include_interfaces)
Finds an inherited component (method or field), taking component visibility into account.
void merge_source_location_rec(exprt &expr, const source_locationt &source_location)
Attaches a source location to an expression and all of its subexpressions.
std::optional< std::string > class_name_from_method_name(const std::string &method_name)
Get JVM type name of the class in which method_name is defined.
const std::string java_class_to_package(const std::string &canonical_classname)
std::string pretty_print_java_type(const std::string &fqn_java_type)
Strip the package name from a java type, for the type to be pretty printed (java::java....
#define JAVA_STRING_LITERAL_PREFIX
API to expression classes for 'mathematical' expressions.
#define UNREACHABLE
This should be used to mark dead code.
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
bool can_cast_type< struct_tag_typet >(const typet &type)
Check whether a reference to a typet is a struct_tag_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
std::string trim_from_last_delimiter(const std::string &s, const char delim)
Return type for get_boxed_type_info_by_name.
Return type for get_java_primitive_type_info.