CBMC
java_bytecode_convert_class.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: JAVA Bytecode Language Conversion
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
13 
14 #ifdef DEBUG
15 #include <iostream>
16 #endif
17 
18 #include "ci_lazy_methods.h"
20 #include "java_root_class.h"
21 #include "java_types.h"
22 #include "java_utils.h"
23 
24 #include <util/arith_tools.h>
25 #include <util/expr_initializer.h>
26 #include <util/namespace.h>
27 #include <util/prefix.h>
28 #include <util/std_expr.h>
29 
31 {
32 public:
34  symbol_tablet &_symbol_table,
35  message_handlert &_message_handler,
36  size_t _max_array_length,
38  java_string_library_preprocesst &_string_preprocess,
39  const std::unordered_set<std::string> &no_load_classes)
40  : log(_message_handler),
41  symbol_table(_symbol_table),
42  max_array_length(_max_array_length),
44  string_preprocess(_string_preprocess),
46  {
47  }
48 
64  void operator()(
66  {
67  PRECONDITION(!parse_trees.empty());
68  const java_bytecode_parse_treet &parse_tree = parse_trees.front();
69 
70  // Add array types to the symbol table
72 
73  const bool loading_success =
74  parse_tree.loading_successful &&
75  !no_load_classes.count(id2string(parse_tree.parsed_class.name));
76  if(loading_success)
77  {
78  overlay_classest overlay_classes;
79  for(auto overlay_class_it = std::next(parse_trees.begin());
80  overlay_class_it != parse_trees.end();
81  ++overlay_class_it)
82  {
83  overlay_classes.push_front(std::cref(overlay_class_it->parsed_class));
84  }
85  convert(parse_tree.parsed_class, overlay_classes);
86  }
87 
88  // Add as string type if relevant
89  const irep_idt &class_name = parse_tree.parsed_class.name;
92  else if(!loading_success)
93  // Generate stub if couldn't load from bytecode and wasn't string type
95  class_name,
99  }
100 
105 
106 private:
109  const size_t max_array_length;
112 
113  // conversion
114  typedef std::list<std::reference_wrapper<const classt>> overlay_classest;
115  void convert(const classt &c, const overlay_classest &overlay_classes);
116  void convert(symbolt &class_symbol, const fieldt &f);
117 
133  static bool is_overlay_method(const methodt &method)
134  {
135  return method.has_annotation(ID_overlay_method);
136  }
137 
158  static bool is_ignored_method(
159  const irep_idt &class_name, const methodt &method)
160  {
161  static irep_idt org_cprover_CProver_name = "org.cprover.CProver";
162  return
163  (class_name == org_cprover_CProver_name &&
164  cprover_methods_to_ignore.count(id2string(method.name)) != 0) ||
165  method.has_annotation(ID_ignored_method);
166  }
167 
168  bool check_field_exists(
169  const fieldt &field,
170  const irep_idt &qualified_fieldname,
171  const struct_union_typet::componentst &fields) const;
172 
173  std::unordered_set<std::string> no_load_classes;
174 };
175 
188 {
189  if(signature.has_value())
190  {
191  // skip the (potential) list of generic parameters at the beginning of the
192  // signature
193  const size_t start =
194  signature.value().front() == '<'
195  ? find_closing_delimiter(signature.value(), 0, '<', '>') + 1
196  : 0;
197 
198  // extract the superclass reference
199  const size_t end =
200  find_closing_semi_colon_for_reference_type(signature.value(), start);
201  const std::string superclass_ref =
202  signature.value().substr(start, (end - start) + 1);
203 
204  // if the superclass is generic then the reference is of form
205  // `Lsuperclass-name<generic-types;>;` if it is implicitly generic, then the
206  // reference is of the form
207  // `Lsuperclass-name<Tgeneric-types;>.Innerclass-Name`
208  if(superclass_ref.find('<') != std::string::npos)
209  return superclass_ref;
210  }
211  return {};
212 }
213 
227  const optionalt<std::string> &signature,
228  const std::string &interface_name)
229 {
230  if(signature.has_value())
231  {
232  // skip the (potential) list of generic parameters at the beginning of the
233  // signature
234  size_t start =
235  signature.value().front() == '<'
236  ? find_closing_delimiter(signature.value(), 0, '<', '>') + 1
237  : 0;
238 
239  // skip the superclass reference (if there is at least one interface
240  // reference in the signature, then there is a superclass reference)
241  start =
242  find_closing_semi_colon_for_reference_type(signature.value(), start) + 1;
243 
244  // if the interface name includes package name, convert dots to slashes
245  std::string interface_name_slash_to_dot = interface_name;
246  std::replace(
247  interface_name_slash_to_dot.begin(),
248  interface_name_slash_to_dot.end(),
249  '.',
250  '/');
251 
252  start =
253  signature.value().find("L" + interface_name_slash_to_dot + "<", start);
254  if(start != std::string::npos)
255  {
256  const size_t &end =
257  find_closing_semi_colon_for_reference_type(signature.value(), start);
258  return signature.value().substr(start, (end - start) + 1);
259  }
260  }
261  return {};
262 }
263 
268  const classt &c,
269  const overlay_classest &overlay_classes)
270 {
271  std::string qualified_classname="java::"+id2string(c.name);
272  if(symbol_table.has_symbol(qualified_classname))
273  {
274  log.debug() << "Skip class " << c.name << " (already loaded)"
275  << messaget::eom;
276  return;
277  }
278 
279  java_class_typet class_type;
280  if(c.signature.has_value() && c.signature.value()[0]=='<')
281  {
282  java_generic_class_typet generic_class_type;
283 #ifdef DEBUG
284  std::cout << "INFO: found generic class signature "
285  << c.signature.value()
286  << " in parsed class "
287  << c.name << "\n";
288 #endif
289  try
290  {
291  const std::vector<typet> &generic_types=java_generic_type_from_string(
292  id2string(c.name),
293  c.signature.value());
294  for(const typet &t : generic_types)
295  {
296  generic_class_type.generic_types()
297  .push_back(to_java_generic_parameter(t));
298  }
299  class_type=generic_class_type;
300  }
302  {
303  log.debug() << "Class: " << c.name
304  << "\n could not parse signature: " << c.signature.value()
305  << "\n " << e.what()
306  << "\n ignoring that the class is generic" << messaget::eom;
307  }
308  }
309 
310  class_type.set_tag(c.name);
311  class_type.set_inner_name(c.inner_name);
312  class_type.set_abstract(c.is_abstract);
313  class_type.set_is_annotation(c.is_annotation);
314  class_type.set_interface(c.is_interface);
315  class_type.set_synthetic(c.is_synthetic);
316  class_type.set_final(c.is_final);
317  class_type.set_is_inner_class(c.is_inner_class);
318  class_type.set_is_static_class(c.is_static_class);
320  class_type.set_outer_class(c.outer_class);
321  class_type.set_super_class(c.super_class);
322  if(c.is_enum)
323  {
325  {
326  log.warning() << "Java Enum " << c.name
327  << " won't work properly because max "
328  << "array length (" << max_array_length
329  << ") is less than the "
330  << "enum size (" << c.enum_elements << ")" << messaget::eom;
331  }
332  class_type.set(
333  ID_java_enum_static_unwind,
335  class_type.set_is_enumeration(true);
336  }
337 
338  if(c.is_public)
339  class_type.set_access(ID_public);
340  else if(c.is_protected)
341  class_type.set_access(ID_protected);
342  else if(c.is_private)
343  class_type.set_access(ID_private);
344  else
345  class_type.set_access(ID_default);
346 
347  if(!c.super_class.empty())
348  {
349  const struct_tag_typet base("java::" + id2string(c.super_class));
350 
351  // if the superclass is generic then the class has the superclass reference
352  // including the generic info in its signature
353  // e.g., signature for class 'A<T>' that extends
354  // 'Generic<Integer>' is '<T:Ljava/lang/Object;>LGeneric<LInteger;>;'
355  const optionalt<std::string> &superclass_ref =
357  if(superclass_ref.has_value())
358  {
359  try
360  {
361  const java_generic_struct_tag_typet generic_base(
362  base, superclass_ref.value(), qualified_classname);
363  class_type.add_base(generic_base);
364  }
366  {
367  log.debug() << "Superclass: " << c.super_class
368  << " of class: " << c.name
369  << "\n could not parse signature: "
370  << superclass_ref.value() << "\n " << e.what()
371  << "\n ignoring that the superclass is generic"
372  << messaget::eom;
373  class_type.add_base(base);
374  }
375  }
376  else
377  {
378  class_type.add_base(base);
379  }
380  java_class_typet::componentt base_class_field;
381  base_class_field.type() = class_type.bases().at(0).type();
382  base_class_field.set_name("@" + id2string(c.super_class));
383  base_class_field.set_base_name("@" + id2string(c.super_class));
384  base_class_field.set_pretty_name("@" + id2string(c.super_class));
385  class_type.components().push_back(base_class_field);
386  }
387 
388  // interfaces are recorded as bases
389  for(const auto &interface : c.implements)
390  {
391  const struct_tag_typet base("java::" + id2string(interface));
392 
393  // if the interface is generic then the class has the interface reference
394  // including the generic info in its signature
395  // e.g., signature for class 'A implements GenericInterface<Integer>' is
396  // 'Ljava/lang/Object;LGenericInterface<LInteger;>;'
397  const optionalt<std::string> interface_ref =
399  if(interface_ref.has_value())
400  {
401  try
402  {
403  const java_generic_struct_tag_typet generic_base(
404  base, interface_ref.value(), qualified_classname);
405  class_type.add_base(generic_base);
406  }
408  {
409  log.debug() << "Interface: " << interface << " of class: " << c.name
410  << "\n could not parse signature: " << interface_ref.value()
411  << "\n " << e.what()
412  << "\n ignoring that the interface is generic"
413  << messaget::eom;
414  class_type.add_base(base);
415  }
416  }
417  else
418  {
419  class_type.add_base(base);
420  }
421  }
422 
423  // now do lambda method handles (bootstrap methods)
424  for(const auto &lambda_entry : c.lambda_method_handle_map)
425  {
426  // if the handle is of unknown type, we still need to store it to preserve
427  // the correct indexing (invokedynamic instructions will retrieve
428  // method handles by index)
429  lambda_entry.second.is_unknown_handle()
430  ? class_type.add_unknown_lambda_method_handle()
431  : class_type.add_lambda_method_handle(
432  lambda_entry.second.get_method_descriptor(),
433  lambda_entry.second.handle_type);
434  }
435 
436  // Load annotations
437  if(!c.annotations.empty())
438  convert_annotations(c.annotations, class_type.get_annotations());
439 
440  // the base name is the name of the class without the package
441  const irep_idt base_name = [](const std::string &full_name) {
442  const size_t last_dot = full_name.find_last_of('.');
443  return last_dot == std::string::npos
444  ? full_name
445  : std::string(full_name, last_dot + 1, std::string::npos);
446  }(id2string(c.name));
447 
448  // produce class symbol
449  symbolt new_symbol;
450  new_symbol.base_name = base_name;
451  new_symbol.pretty_name=c.name;
452  new_symbol.name=qualified_classname;
453  class_type.set_name(new_symbol.name);
454  new_symbol.type=class_type;
455  new_symbol.mode=ID_java;
456  new_symbol.is_type=true;
457 
458  symbolt *class_symbol;
459 
460  // add before we do members
461  log.debug() << "Adding symbol: class '" << c.name << "'" << messaget::eom;
462  if(symbol_table.move(new_symbol, class_symbol))
463  {
464  log.error() << "failed to add class symbol " << new_symbol.name
465  << messaget::eom;
466  throw 0;
467  }
468 
469  // Now do fields
470  const class_typet::componentst &fields =
471  to_class_type(class_symbol->type).components();
472  // Include fields from overlay classes as they will be required by the
473  // methods defined there
474  for(auto overlay_class : overlay_classes)
475  {
476  for(const auto &field : overlay_class.get().fields)
477  {
478  std::string field_id = qualified_classname + "." + id2string(field.name);
479  if(check_field_exists(field, field_id, fields))
480  {
481  std::string err =
482  "Duplicate field definition for " + field_id + " in overlay class";
483  // TODO: This could just be a warning if the types match
484  log.error() << err << messaget::eom;
485  throw err.c_str();
486  }
487  log.debug() << "Adding symbol from overlay class: field '" << field.name
488  << "'" << messaget::eom;
489  convert(*class_symbol, field);
490  POSTCONDITION(check_field_exists(field, field_id, fields));
491  }
492  }
493  for(const auto &field : c.fields)
494  {
495  std::string field_id = qualified_classname + "." + id2string(field.name);
496  if(check_field_exists(field, field_id, fields))
497  {
498  // TODO: This could be a warning if the types match
499  log.error() << "Field definition for " << field_id
500  << " already loaded from overlay class" << messaget::eom;
501  continue;
502  }
503  log.debug() << "Adding symbol: field '" << field.name << "'"
504  << messaget::eom;
505  convert(*class_symbol, field);
506  POSTCONDITION(check_field_exists(field, field_id, fields));
507  }
508 
509  // Now do methods
510  std::set<irep_idt> overlay_methods;
511  for(auto overlay_class : overlay_classes)
512  {
513  for(const methodt &method : overlay_class.get().methods)
514  {
515  const irep_idt method_identifier =
516  qualified_classname + "." + id2string(method.name)
517  + ":" + method.descriptor;
518  if(is_ignored_method(c.name, method))
519  {
520  log.debug() << "Ignoring method: '" << method_identifier << "'"
521  << messaget::eom;
522  continue;
523  }
524  if(method_bytecode.contains_method(method_identifier))
525  {
526  // This method has already been discovered and added to method_bytecode
527  // while parsing an overlay class that appears later in the classpath
528  // (we're working backwards)
529  // Warn the user if the definition already found was not an overlay,
530  // otherwise simply don't load this earlier definition
531  if(overlay_methods.count(method_identifier) == 0)
532  {
533  // This method was defined in a previous class definition without
534  // being marked as an overlay method
535  log.warning()
536  << "Method " << method_identifier
537  << " exists in an overlay class without being marked as an "
538  "overlay and also exists in another overlay class that appears "
539  "earlier in the classpath"
540  << messaget::eom;
541  }
542  continue;
543  }
544  // Always run the lazy pre-stage, as it symbol-table
545  // registers the function.
546  log.debug() << "Adding symbol from overlay class: method '"
547  << method_identifier << "'" << messaget::eom;
548  java_bytecode_convert_method_lazy(
549  *class_symbol,
550  method_identifier,
551  method,
552  symbol_table,
553  log.get_message_handler());
554  method_bytecode.add(qualified_classname, method_identifier, method);
555  if(is_overlay_method(method))
556  overlay_methods.insert(method_identifier);
557  }
558  }
559  for(const methodt &method : c.methods)
560  {
561  const irep_idt method_identifier=
562  qualified_classname + "." + id2string(method.name)
563  + ":" + method.descriptor;
564  if(is_ignored_method(c.name, method))
565  {
566  log.debug() << "Ignoring method: '" << method_identifier << "'"
567  << messaget::eom;
568  continue;
569  }
570  if(method_bytecode.contains_method(method_identifier))
571  {
572  // This method has already been discovered while parsing an overlay
573  // class
574  // If that definition is an overlay then we simply don't load this
575  // original definition and we remove it from the list of overlays
576  if(overlay_methods.erase(method_identifier) == 0)
577  {
578  // This method was defined in a previous class definition without
579  // being marked as an overlay method
580  log.warning()
581  << "Method " << method_identifier
582  << " exists in an overlay class without being marked as an overlay "
583  "and also exists in the underlying class"
584  << messaget::eom;
585  }
586  continue;
587  }
588  // Always run the lazy pre-stage, as it symbol-table
589  // registers the function.
590  log.debug() << "Adding symbol: method '" << method_identifier << "'"
591  << messaget::eom;
592  java_bytecode_convert_method_lazy(
593  *class_symbol,
594  method_identifier,
595  method,
596  symbol_table,
597  log.get_message_handler());
598  method_bytecode.add(qualified_classname, method_identifier, method);
599  if(is_overlay_method(method))
600  {
601  log.warning()
602  << "Method " << method_identifier
603  << " marked as an overlay where defined in the underlying class"
604  << messaget::eom;
605  }
606  }
607  if(!overlay_methods.empty())
608  {
609  log.error()
610  << "Overlay methods defined in overlay classes did not exist in the "
611  "underlying class:\n";
612  for(const irep_idt &method_id : overlay_methods)
613  log.error() << " " << method_id << "\n";
614  log.error() << messaget::eom;
615  }
616 
617  // is this a root class?
618  if(c.super_class.empty())
619  java_root_class(*class_symbol);
620 }
621 
622 bool java_bytecode_convert_classt::check_field_exists(
623  const java_bytecode_parse_treet::fieldt &field,
624  const irep_idt &qualified_fieldname,
625  const struct_union_typet::componentst &fields) const
626 {
627  if(field.is_static)
628  return symbol_table.has_symbol(qualified_fieldname);
629 
630  auto existing_field = std::find_if(
631  fields.begin(),
632  fields.end(),
633  [&field](const struct_union_typet::componentt &f)
634  {
635  return f.get_name() == field.name;
636  });
637  return existing_field != fields.end();
638 }
639 
643 void java_bytecode_convert_classt::convert(
644  symbolt &class_symbol,
645  const fieldt &f)
646 {
647  typet field_type;
648  if(f.signature.has_value())
649  {
650  field_type = *java_type_from_string_with_exception(
651  f.descriptor, f.signature, id2string(class_symbol.name));
652 
654  if(is_java_generic_parameter(field_type))
655  {
656 #ifdef DEBUG
657  std::cout << "fieldtype: generic "
658  << to_java_generic_parameter(field_type).type_variable()
659  .get_identifier()
660  << " name " << f.name << "\n";
661 #endif
662  }
663 
666  else if(is_java_generic_type(field_type))
667  {
668  java_generic_typet &with_gen_type=
669  to_java_generic_type(field_type);
670 #ifdef DEBUG
671  std::cout << "fieldtype: generic container type "
672  << std::to_string(with_gen_type.generic_type_arguments().size())
673  << " type " << with_gen_type.id()
674  << " name " << f.name
675  << " subtype id " << with_gen_type.subtype().id() << "\n";
676 #endif
677  field_type=with_gen_type;
678  }
679  }
680  else
681  field_type = *java_type_from_string(f.descriptor);
682 
683  // determine access
684  irep_idt access;
685 
686  if(f.is_private)
687  access = ID_private;
688  else if(f.is_protected)
689  access = ID_protected;
690  else if(f.is_public)
691  access = ID_public;
692  else
693  access = ID_default;
694 
695  auto &class_type = to_java_class_type(class_symbol.type);
696 
697  // is this a static field?
698  if(f.is_static)
699  {
700  const irep_idt field_identifier =
701  id2string(class_symbol.name) + "." + id2string(f.name);
702 
703  class_type.static_members().emplace_back();
704  auto &component = class_type.static_members().back();
705 
706  component.set_name(field_identifier);
707  component.set_base_name(f.name);
708  component.set_pretty_name(f.name);
709  component.set_access(access);
710  component.set_is_final(f.is_final);
711  component.type() = field_type;
712 
713  // Create the symbol
714  symbolt new_symbol;
715 
716  new_symbol.is_static_lifetime=true;
717  new_symbol.is_lvalue=true;
718  new_symbol.is_state_var=true;
719  new_symbol.name=id2string(class_symbol.name)+"."+id2string(f.name);
720  new_symbol.base_name=f.name;
721  new_symbol.type=field_type;
722  // Provide a static field -> class link, like
723  // java_bytecode_convert_method::convert does for method -> class.
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);
729  new_symbol.mode=ID_java;
730  new_symbol.is_type=false;
731 
732  // These annotations use `ID_C_access` instead of `ID_access` like methods
733  // to avoid type clashes in expressions like `some_static_field = 0`, where
734  // with ID_access the constant '0' would need to have an access modifier
735  // too, or else appear to have incompatible type.
736  if(f.is_public)
737  new_symbol.type.set(ID_C_access, ID_public);
738  else if(f.is_protected)
739  new_symbol.type.set(ID_C_access, ID_protected);
740  else if(f.is_private)
741  new_symbol.type.set(ID_C_access, ID_private);
742  else
743  new_symbol.type.set(ID_C_access, ID_default);
744 
745  const namespacet ns(symbol_table);
746  const auto value = zero_initializer(field_type, class_symbol.location, ns);
747  if(!value.has_value())
748  {
749  log.error().source_location = class_symbol.location;
750  log.error() << "failed to zero-initialize " << f.name << messaget::eom;
751  throw 0;
752  }
753  new_symbol.value = *value;
754 
755  // Load annotations
756  if(!f.annotations.empty())
757  {
758  convert_annotations(
759  f.annotations,
760  type_checked_cast<annotated_typet>(new_symbol.type).get_annotations());
761  }
762 
763  // Do we have the static field symbol already?
764  const auto s_it=symbol_table.symbols.find(new_symbol.name);
765  if(s_it!=symbol_table.symbols.end())
766  symbol_table.erase(s_it); // erase, we stubbed it
767 
768  if(symbol_table.add(new_symbol))
769  assert(false && "failed to add static field symbol");
770  }
771  else
772  {
773  class_type.components().emplace_back();
774  auto &component = class_type.components().back();
775 
776  component.set_name(f.name);
777  component.set_base_name(f.name);
778  component.set_pretty_name(f.name);
779  component.set_access(access);
780  component.set_is_final(f.is_final);
781  component.type() = field_type;
782 
783  // Load annotations
784  if(!f.annotations.empty())
785  {
786  convert_annotations(
787  f.annotations,
788  static_cast<annotated_typet &>(component.type()).get_annotations());
789  }
790  }
791 }
792 
793 void add_java_array_types(symbol_tablet &symbol_table)
794 {
795  const std::string letters="ijsbcfdza";
796 
797  for(const char l : letters)
798  {
799  struct_tag_typet struct_tag_type =
800  to_struct_tag_type(java_array_type(l).subtype());
801 
802  const irep_idt &struct_tag_type_identifier =
803  struct_tag_type.get_identifier();
804  if(symbol_table.has_symbol(struct_tag_type_identifier))
805  return;
806 
807  java_class_typet class_type;
808  // we have the base class, java.lang.Object, length and data
809  // of appropriate type
810  class_type.set_tag(struct_tag_type_identifier);
811  // Note that non-array types don't have "java::" at the beginning of their
812  // tag, and their name is "java::" + their tag. Since arrays do have
813  // "java::" at the beginning of their tag we set the name to be the same as
814  // the tag.
815  class_type.set_name(struct_tag_type_identifier);
816 
817  class_type.components().reserve(3);
818  java_class_typet::componentt base_class_component(
819  "@java.lang.Object", struct_tag_typet("java::java.lang.Object"));
820  base_class_component.set_pretty_name("@java.lang.Object");
821  base_class_component.set_base_name("@java.lang.Object");
822  class_type.components().push_back(base_class_component);
823 
824  java_class_typet::componentt length_component("length", java_int_type());
825  length_component.set_pretty_name("length");
826  length_component.set_base_name("length");
827  class_type.components().push_back(length_component);
828 
829  java_class_typet::componentt data_component(
830  "data", java_reference_type(java_type_from_char(l)));
831  data_component.set_pretty_name("data");
832  data_component.set_base_name("data");
833  class_type.components().push_back(data_component);
834 
835  if(l == 'a')
836  {
837  // This is a reference array (java::array[reference]). Add extra fields to
838  // carry the innermost element type and array dimension.
839  java_class_typet::componentt array_element_classid_component(
840  JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME, string_typet());
841  array_element_classid_component.set_pretty_name(
842  JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
843  array_element_classid_component.set_base_name(
844  JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
845  class_type.components().push_back(array_element_classid_component);
846 
847  java_class_typet::componentt array_dimension_component(
848  JAVA_ARRAY_DIMENSION_FIELD_NAME, java_int_type());
849  array_dimension_component.set_pretty_name(
850  JAVA_ARRAY_DIMENSION_FIELD_NAME);
851  array_dimension_component.set_base_name(JAVA_ARRAY_DIMENSION_FIELD_NAME);
852  class_type.components().push_back(array_dimension_component);
853  }
854 
855  class_type.add_base(struct_tag_typet("java::java.lang.Object"));
856 
857  INVARIANT(
858  is_valid_java_array(class_type),
859  "Constructed a new type representing a Java Array "
860  "object that doesn't match expectations");
861 
862  symbolt symbol;
863  symbol.name = struct_tag_type_identifier;
864  symbol.base_name = struct_tag_type.get(ID_C_base_name);
865  symbol.is_type=true;
866  symbol.type = class_type;
867  symbol.mode = ID_java;
868  symbol_table.add(symbol);
869 
870  // Also provide a clone method:
871  // ----------------------------
872 
873  const irep_idt clone_name =
874  id2string(struct_tag_type_identifier) + ".clone:()Ljava/lang/Object;";
875  java_method_typet::parametert this_param(
876  java_reference_type(struct_tag_type));
877  this_param.set_identifier(id2string(clone_name)+"::this");
878  this_param.set_base_name(ID_this);
879  this_param.set_this();
880  const java_method_typet clone_type({this_param}, java_lang_object_type());
881 
882  parameter_symbolt this_symbol;
883  this_symbol.name=this_param.get_identifier();
884  this_symbol.base_name=this_param.get_base_name();
885  this_symbol.pretty_name=this_symbol.base_name;
886  this_symbol.type=this_param.type();
887  this_symbol.mode=ID_java;
888  symbol_table.add(this_symbol);
889 
890  const irep_idt local_name=
891  id2string(clone_name)+"::cloned_array";
892  auxiliary_symbolt local_symbol;
893  local_symbol.name=local_name;
894  local_symbol.base_name="cloned_array";
895  local_symbol.pretty_name=local_symbol.base_name;
896  local_symbol.type = java_reference_type(struct_tag_type);
897  local_symbol.mode=ID_java;
898  symbol_table.add(local_symbol);
899  const auto local_symexpr = local_symbol.symbol_expr();
900 
901  code_declt declare_cloned(local_symexpr);
902 
903  source_locationt location;
904  location.set_function(local_name);
905  side_effect_exprt java_new_array(
906  ID_java_new_array, java_reference_type(struct_tag_type), location);
907  dereference_exprt old_array{this_symbol.symbol_expr()};
908  dereference_exprt new_array{local_symexpr};
909  member_exprt old_length(
910  old_array, length_component.get_name(), length_component.type());
911  java_new_array.copy_to_operands(old_length);
912  code_frontend_assignt create_blank(local_symexpr, java_new_array);
913 
914  codet copy_type_information = code_skipt();
915  if(l == 'a')
916  {
917  // Reference arrays carry additional type information in their classids
918  // which should be copied:
919  const auto &array_dimension_component =
920  class_type.get_component(JAVA_ARRAY_DIMENSION_FIELD_NAME);
921  const auto &array_element_classid_component =
922  class_type.get_component(JAVA_ARRAY_ELEMENT_CLASSID_FIELD_NAME);
923 
924  member_exprt old_array_dimension(old_array, array_dimension_component);
925  member_exprt old_array_element_classid(
926  old_array, array_element_classid_component);
927 
928  member_exprt new_array_dimension(new_array, array_dimension_component);
929  member_exprt new_array_element_classid(
930  new_array, array_element_classid_component);
931 
932  copy_type_information = code_blockt{
933  {code_frontend_assignt(new_array_dimension, old_array_dimension),
934  code_frontend_assignt(
935  new_array_element_classid, old_array_element_classid)}};
936  }
937 
938  member_exprt old_data(
939  old_array, data_component.get_name(), data_component.type());
940  member_exprt new_data(
941  new_array, data_component.get_name(), data_component.type());
942 
943  /*
944  // TODO use this instead of a loop.
945  codet array_copy;
946  array_copy.set_statement(ID_array_copy);
947  array_copy.add_to_operands(std::move(new_data), std::move(old_data));
948  clone_body.add_to_operands(std::move(array_copy));
949  */
950 
951  // Begin for-loop to replace:
952 
953  const irep_idt index_name=
954  id2string(clone_name)+"::index";
955  auxiliary_symbolt index_symbol;
956  index_symbol.name=index_name;
957  index_symbol.base_name="index";
958  index_symbol.pretty_name=index_symbol.base_name;
959  index_symbol.type = length_component.type();
960  index_symbol.mode=ID_java;
961  symbol_table.add(index_symbol);
962  const auto &index_symexpr=index_symbol.symbol_expr();
963 
964  code_declt declare_index(index_symexpr);
965 
966  dereference_exprt old_cell(
967  plus_exprt(old_data, index_symexpr),
968  to_type_with_subtype(old_data.type()).subtype());
969  dereference_exprt new_cell(
970  plus_exprt(new_data, index_symexpr),
971  to_type_with_subtype(new_data.type()).subtype());
972 
973  const code_fort copy_loop = code_fort::from_index_bounds(
974  from_integer(0, index_symexpr.type()),
975  old_length,
976  index_symexpr,
977  code_frontend_assignt(std::move(new_cell), std::move(old_cell)),
978  location);
979 
980  member_exprt new_base_class(
981  new_array, base_class_component.get_name(), base_class_component.type());
982  address_of_exprt retval(new_base_class);
983  code_returnt return_inst(retval);
984 
985  const code_blockt clone_body({declare_cloned,
986  create_blank,
987  copy_type_information,
988  declare_index,
989  copy_loop,
990  return_inst});
991 
992  symbolt clone_symbol;
993  clone_symbol.name=clone_name;
994  clone_symbol.pretty_name =
995  id2string(struct_tag_type_identifier) + ".clone:()";
996  clone_symbol.base_name="clone";
997  clone_symbol.type=clone_type;
998  clone_symbol.value=clone_body;
999  clone_symbol.mode=ID_java;
1000  symbol_table.add(clone_symbol);
1001  }
1002 }
1003 
1004 bool java_bytecode_convert_class(
1005  const java_class_loadert::parse_tree_with_overlayst &parse_trees,
1006  symbol_tablet &symbol_table,
1007  message_handlert &message_handler,
1008  size_t max_array_length,
1009  method_bytecodet &method_bytecode,
1010  java_string_library_preprocesst &string_preprocess,
1011  const std::unordered_set<std::string> &no_load_classes)
1012 {
1013  java_bytecode_convert_classt java_bytecode_convert_class(
1014  symbol_table,
1015  message_handler,
1016  max_array_length,
1017  method_bytecode,
1018  string_preprocess,
1019  no_load_classes);
1020 
1021  try
1022  {
1023  java_bytecode_convert_class(parse_trees);
1024  return false;
1025  }
1026 
1027  catch(int)
1028  {
1029  }
1030 
1031  catch(const char *e)
1032  {
1033  messaget log{message_handler};
1034  log.error() << e << messaget::eom;
1035  }
1036 
1037  catch(const std::string &e)
1038  {
1039  messaget log{message_handler};
1040  log.error() << e << messaget::eom;
1041  }
1042 
1043  return true;
1044 }
1045 
1046 static std::string get_final_name_component(const std::string &name)
1047 {
1048  return name.substr(name.rfind("::") + 2);
1049 }
1050 
1051 static std::string get_without_final_name_component(const std::string &name)
1052 {
1053  return name.substr(0, name.rfind("::"));
1054 }
1055 
1068 static void find_and_replace_parameter(
1069  java_generic_parametert &parameter,
1070  const std::vector<java_generic_parametert> &replacement_parameters)
1071 {
1072  // get the name of the parameter, e.g., `T` from `java::Class::T`
1073  const std::string &parameter_full_name =
1074  id2string(parameter.type_variable_ref().get_identifier());
1075  const std::string parameter_name =
1076  get_final_name_component(parameter_full_name);
1077 
1078  // check if there is a replacement parameter with the same name
1079  const auto replacement_parameter_it = std::find_if(
1080  replacement_parameters.begin(),
1081  replacement_parameters.end(),
1082  [&parameter_name](const java_generic_parametert &replacement_param) {
1083  return parameter_name ==
1084  get_final_name_component(
1085  id2string(replacement_param.type_variable().get_identifier()));
1086  });
1087  if(replacement_parameter_it == replacement_parameters.end())
1088  return;
1089 
1090  // A replacement parameter was found, update the identifier
1091  const std::string &replacement_parameter_full_name =
1092  id2string(replacement_parameter_it->type_variable().get_identifier());
1093 
1094  // Check the replacement parameter comes from an outer class
1095  PRECONDITION(has_prefix(
1096  replacement_parameter_full_name,
1097  get_without_final_name_component(parameter_full_name)));
1098 
1099  parameter.type_variable_ref().set_identifier(replacement_parameter_full_name);
1100 }
1101 
1107 static void find_and_replace_parameters(
1108  typet &type,
1109  const std::vector<java_generic_parametert> &replacement_parameters)
1110 {
1111  if(is_java_generic_parameter(type))
1112  {
1113  find_and_replace_parameter(
1114  to_java_generic_parameter(type), replacement_parameters);
1115  }
1116  else if(is_java_generic_type(type))
1117  {
1118  java_generic_typet &generic_type = to_java_generic_type(type);
1119  std::vector<reference_typet> &arguments =
1120  generic_type.generic_type_arguments();
1121  for(auto &argument : arguments)
1122  {
1123  find_and_replace_parameters(argument, replacement_parameters);
1124  }
1125  }
1126  else if(is_java_generic_struct_tag_type(type))
1127  {
1128  java_generic_struct_tag_typet &generic_base =
1129  to_java_generic_struct_tag_type(type);
1130  std::vector<reference_typet> &gen_types = generic_base.generic_types();
1131  for(auto &gen_type : gen_types)
1132  {
1133  find_and_replace_parameters(gen_type, replacement_parameters);
1134  }
1135  }
1136 }
1137 
1141 void convert_annotations(
1142  const java_bytecode_parse_treet::annotationst &parsed_annotations,
1143  std::vector<java_annotationt> &java_annotations)
1144 {
1145  for(const auto &annotation : parsed_annotations)
1146  {
1147  java_annotations.emplace_back(annotation.type);
1148  std::vector<java_annotationt::valuet> &values =
1149  java_annotations.back().get_values();
1150  std::transform(
1151  annotation.element_value_pairs.begin(),
1152  annotation.element_value_pairs.end(),
1153  std::back_inserter(values),
1154  [](const decltype(annotation.element_value_pairs)::value_type &value) {
1155  return java_annotationt::valuet(value.element_name, value.value);
1156  });
1157  }
1158 }
1159 
1164 void convert_java_annotations(
1165  const std::vector<java_annotationt> &java_annotations,
1166  java_bytecode_parse_treet::annotationst &annotations)
1167 {
1168  for(const auto &java_annotation : java_annotations)
1169  {
1170  annotations.emplace_back(java_bytecode_parse_treet::annotationt());
1171  auto &annotation = annotations.back();
1172  annotation.type = java_annotation.get_type();
1173 
1174  std::transform(
1175  java_annotation.get_values().begin(),
1176  java_annotation.get_values().end(),
1177  std::back_inserter(annotation.element_value_pairs),
1178  [](const java_annotationt::valuet &value)
1179  -> java_bytecode_parse_treet::annotationt::element_value_pairt {
1180  return {value.get_name(), value.get_value()};
1181  });
1182  }
1183 }
1184 
1189 void mark_java_implicitly_generic_class_type(
1190  const irep_idt &class_name,
1191  symbol_tablet &symbol_table)
1192 {
1193  const std::string qualified_class_name = "java::" + id2string(class_name);
1194  PRECONDITION(symbol_table.has_symbol(qualified_class_name));
1195  // This will have its type changed
1196  symbolt &class_symbol = symbol_table.get_writeable_ref(qualified_class_name);
1197  const java_class_typet &class_type = to_java_class_type(class_symbol.type);
1198 
1199  // the class must be an inner non-static class, i.e., have a field this$*
1200  // TODO this should be simplified once static inner classes are marked
1201  // during parsing
1202  bool no_this_field = std::none_of(
1203  class_type.components().begin(),
1204  class_type.components().end(),
1205  [](const struct_union_typet::componentt &component)
1206  {
1207  return id2string(component.get_name()).substr(0, 5) == "this$";
1208  });
1209  if(no_this_field)
1210  {
1211  return;
1212  }
1213 
1214  // create a vector of all generic type parameters of all outer classes, in
1215  // the order from the outer-most inwards
1216  std::vector<java_generic_parametert> implicit_generic_type_parameters;
1217  std::string::size_type outer_class_delimiter =
1218  qualified_class_name.rfind('$');
1219  while(outer_class_delimiter != std::string::npos)
1220  {
1221  std::string outer_class_name =
1222  qualified_class_name.substr(0, outer_class_delimiter);
1223  if(symbol_table.has_symbol(outer_class_name))
1224  {
1225  const symbolt &outer_class_symbol =
1226  symbol_table.lookup_ref(outer_class_name);
1227  const java_class_typet &outer_class_type =
1228  to_java_class_type(outer_class_symbol.type);
1229  if(is_java_generic_class_type(outer_class_type))
1230  {
1231  for(const java_generic_parametert &outer_generic_type_parameter :
1232  to_java_generic_class_type(outer_class_type).generic_types())
1233  {
1234  // Create a new generic type parameter with name in the form:
1235  // java::Outer$Inner::Outer::T
1236  irep_idt identifier = qualified_class_name + "::" +
1237  id2string(strip_java_namespace_prefix(
1238  outer_generic_type_parameter.get_name()));
1239  java_generic_parameter_tagt bound = to_java_generic_parameter_tag(
1240  outer_generic_type_parameter.base_type());
1241  bound.type_variable_ref().set_identifier(identifier);
1242  implicit_generic_type_parameters.emplace_back(identifier, bound);
1243  }
1244  }
1245  outer_class_delimiter = outer_class_name.rfind('$');
1246  }
1247  else
1248  {
1249  throw missing_outer_class_symbol_exceptiont(
1250  outer_class_name, qualified_class_name);
1251  }
1252  }
1253 
1254  // if there are any implicit generic type parameters, mark the class
1255  // implicitly generic and update identifiers of type parameters used in fields
1256  if(!implicit_generic_type_parameters.empty())
1257  {
1258  java_implicitly_generic_class_typet new_class_type(
1259  class_type, implicit_generic_type_parameters);
1260 
1261  // Prepend existing parameters so choose those above any inherited
1262  if(is_java_generic_class_type(class_type))
1263  {
1264  const java_generic_class_typet::generic_typest &class_type_params =
1265  to_java_generic_class_type(class_type).generic_types();
1266  implicit_generic_type_parameters.insert(
1267  implicit_generic_type_parameters.begin(),
1268  class_type_params.begin(),
1269  class_type_params.end());
1270  }
1271 
1272  for(auto &field : new_class_type.components())
1273  {
1274  find_and_replace_parameters(
1275  field.type(), implicit_generic_type_parameters);
1276  }
1277 
1278  for(auto &base : new_class_type.bases())
1279  {
1280  find_and_replace_parameters(
1281  base.type(), implicit_generic_type_parameters);
1282  }
1283 
1284  class_symbol.type = new_class_type;
1285  }
1286 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
java_bytecode_parse_treet::classt::implements
implementst implements
Definition: java_bytecode_parse_tree.h:275
java_bytecode_parse_treet::loading_successful
bool loading_successful
Definition: java_bytecode_parse_tree.h:318
method_bytecodet
Definition: ci_lazy_methods.h:32
symbol_table_baset::has_symbol
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
Definition: symbol_table_base.h:87
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
java_class_typet::componentt
Definition: java_types.h:199
java_root_class.h
java_bytecode_parse_treet::classt::is_annotation
bool is_annotation
Definition: java_bytecode_parse_tree.h:219
arith_tools.h
java_class_typet::set_synthetic
void set_synthetic(bool synthetic)
marks class synthetic
Definition: java_types.h:434
java_class_typet::set_is_static_class
void set_is_static_class(const bool &is_static_class)
Definition: java_types.h:368
java_class_typet::set_is_anonymous_class
void set_is_anonymous_class(const bool &is_anonymous_class)
Definition: java_types.h:378
java_bytecode_parse_treet
Definition: java_bytecode_parse_tree.h:22
typet
The type of an expression, extends irept.
Definition: type.h:28
java_bytecode_parse_treet::methodt
Definition: java_bytecode_parse_tree.h:84
java_bytecode_convert_classt::log
messaget log
Definition: java_bytecode_convert_class.cpp:107
unsupported_java_class_signature_exceptiont
An exception that is raised for unsupported class signature.
Definition: java_types.h:1131
struct_typet::add_base
void add_base(const struct_tag_typet &base)
Add a base class/struct.
Definition: std_types.cpp:98
java_bytecode_convert_classt::convert
void convert(const classt &c, const overlay_classest &overlay_classes)
Convert a class, adding symbols to the symbol table for its members.
Definition: java_bytecode_convert_class.cpp:267
java_bytecode_parse_treet::classt::is_synthetic
bool is_synthetic
Definition: java_bytecode_parse_tree.h:218
prefix.h
replace
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
Definition: string_constraint.cpp:70
java_bytecode_convert_classt::is_ignored_method
static bool is_ignored_method(const irep_idt &class_name, const methodt &method)
Check if a method is an ignored method, by one of two mechanisms:
Definition: java_bytecode_convert_class.cpp:158
generate_class_stub
void generate_class_stub(const irep_idt &class_name, symbol_table_baset &symbol_table, message_handlert &message_handler, const struct_union_typet::componentst &componentst)
Definition: java_utils.cpp:161
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
java_bytecode_convert_classt::java_bytecode_convert_classt
java_bytecode_convert_classt(symbol_tablet &_symbol_table, message_handlert &_message_handler, size_t _max_array_length, method_bytecodet &method_bytecode, java_string_library_preprocesst &_string_preprocess, const std::unordered_set< std::string > &no_load_classes)
Definition: java_bytecode_convert_class.cpp:33
struct_tag_typet
A struct tag type, i.e., struct_typet with an identifier.
Definition: std_types.h:448
java_class_typet::set_is_annotation
void set_is_annotation(bool is_annotation)
marks class an annotation
Definition: java_types.h:446
java_bytecode_parse_treet::classt::is_final
bool is_final
Definition: java_bytecode_parse_tree.h:216
java_bytecode_parse_treet::classt::is_inner_class
bool is_inner_class
Definition: java_bytecode_parse_tree.h:220
java_bytecode_convert_classt::methodt
java_bytecode_parse_treet::methodt methodt
Definition: java_bytecode_convert_class.cpp:103
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
messaget::eom
static eomt eom
Definition: message.h:297
namespace.h
java_bytecode_convert_classt::no_load_classes
std::unordered_set< std::string > no_load_classes
Definition: java_bytecode_convert_class.cpp:173
java_bytecode_parse_treet::membert::has_annotation
bool has_annotation(const irep_idt &annotation_id) const
Definition: java_bytecode_parse_tree.h:78
java_class_typet::set_inner_name
void set_inner_name(const irep_idt &name)
Set the name of a java inner class.
Definition: java_types.h:576
java_class_typet
Definition: java_types.h:196
java_bytecode_convert_classt::annotationt
java_bytecode_parse_treet::annotationt annotationt
Definition: java_bytecode_convert_class.cpp:104
java_generic_class_typet::generic_types
const generic_typest & generic_types() const
Definition: java_types.h:982
java_bytecode_parse_treet::classt::is_public
bool is_public
Definition: java_bytecode_parse_tree.h:215
java_bytecode_convert_classt::fieldt
java_bytecode_parse_treet::fieldt fieldt
Definition: java_bytecode_convert_class.cpp:102
java_string_library_preprocesst::add_string_type
void add_string_type(const irep_idt &class_name, symbol_tablet &symbol_table)
Add to the symbol table type declaration for a String-like Java class.
Definition: java_string_library_preprocess.cpp:217
java_bytecode_convert_classt::overlay_classest
std::list< std::reference_wrapper< const classt > > overlay_classest
Definition: java_bytecode_convert_class.cpp:114
find_closing_delimiter
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.
Definition: java_utils.cpp:305
java_class_typet::set_is_enumeration
void set_is_enumeration(const bool is_enumeration)
marks class as an enumeration
Definition: java_types.h:410
java_bytecode_parse_treet::classt::enum_elements
size_t enum_elements
Definition: java_bytecode_parse_tree.h:225
expr_initializer.h
java_bytecode_convert_classt::classt
java_bytecode_parse_treet::classt classt
Definition: java_bytecode_convert_class.cpp:101
java_class_loadert::parse_tree_with_overlayst
std::list< java_bytecode_parse_treet > parse_tree_with_overlayst
A list of parse trees supporting overlay classes.
Definition: java_class_loader.h:29
java_bytecode_convert_classt::string_preprocess
java_string_library_preprocesst & string_preprocess
Definition: java_bytecode_convert_class.cpp:111
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
java_bytecode_parse_treet::classt::is_enum
bool is_enum
Definition: java_bytecode_parse_tree.h:214
java_bytecode_parse_treet::annotationt
Definition: java_bytecode_parse_tree.h:32
struct_union_typet::set_tag
void set_tag(const irep_idt &tag)
Definition: std_types.h:169
find_closing_semi_colon_for_reference_type
size_t find_closing_semi_colon_for_reference_type(const std::string src, size_t starting_point)
Finds the closing semi-colon ending a ClassTypeSignature that starts at starting_point.
Definition: java_types.cpp:516
java_bytecode_parse_treet::classt::name
irep_idt name
Definition: java_bytecode_parse_tree.h:212
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
add_java_array_types
void add_java_array_types(symbol_tablet &symbol_table)
Register in the symbol_table new symbols for the objects java::array[X] where X is byte,...
Definition: java_bytecode_convert_class.cpp:793
extract_generic_interface_reference
static optionalt< std::string > extract_generic_interface_reference(const optionalt< std::string > &signature, const std::string &interface_name)
Auxiliary function to extract the generic interface reference of an interface with the specified name...
Definition: java_bytecode_convert_class.cpp:226
struct_typet::bases
const basest & bases() const
Get the collection of base classes/structs.
Definition: std_types.h:262
message_handlert
Definition: message.h:27
java_bytecode_convert_method.h
dstringt::empty
bool empty() const
Definition: dstring.h:88
java_bytecode_parse_treet::classt::is_private
bool is_private
Definition: java_bytecode_parse_tree.h:215
cprover_methods_to_ignore
const std::unordered_set< std::string > cprover_methods_to_ignore
Methods belonging to the class org.cprover.CProver that should be ignored (not converted),...
Definition: java_utils.cpp:532
extract_generic_superclass_reference
static optionalt< std::string > extract_generic_superclass_reference(const optionalt< std::string > &signature)
Auxiliary function to extract the generic superclass reference from the class signature.
Definition: java_bytecode_convert_class.cpp:187
java_bytecode_convert_classt::is_overlay_method
static bool is_overlay_method(const methodt &method)
Check if a method is an overlay method by searching for ID_overlay_method in its list of annotations.
Definition: java_bytecode_convert_class.cpp:133
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
ci_lazy_methods.h
java_class_typet::set_final
void set_final(bool is_final)
Definition: java_types.h:388
java_class_typet::set_interface
void set_interface(bool interface)
marks class an interface
Definition: java_types.h:458
java_class_typet::set_outer_class
void set_outer_class(const irep_idt &outer_class)
Definition: java_types.h:348
java_bytecode_parse_treet::classt::is_protected
bool is_protected
Definition: java_bytecode_parse_tree.h:215
java_class_typet::set_super_class
void set_super_class(const irep_idt &super_class)
Definition: java_types.h:358
java_bytecode_convert_classt::symbol_table
symbol_tablet & symbol_table
Definition: java_bytecode_convert_class.cpp:108
java_class_typet::components
const componentst & components() const
Definition: java_types.h:224
java_bytecode_parse_treet::parsed_class
classt parsed_class
Definition: java_bytecode_parse_tree.h:310
messaget::get_message_handler
message_handlert & get_message_handler()
Definition: message.h:184
java_bytecode_convert_classt::method_bytecode
method_bytecodet & method_bytecode
Definition: java_bytecode_convert_class.cpp:110
java_bytecode_parse_treet::membert::name
irep_idt name
Definition: java_bytecode_parse_tree.h:68
java_class_typet::set_access
void set_access(const irep_idt &access)
Definition: java_types.h:328
to_java_generic_parameter
const java_generic_parametert & to_java_generic_parameter(const typet &type)
Definition: java_types.h:827
symbolt
Symbol table entry.
Definition: symbol.h:27
java_bytecode_parse_treet::classt::is_static_class
bool is_static_class
Definition: java_bytecode_parse_tree.h:221
java_string_library_preprocesst
Definition: java_string_library_preprocess.h:36
java_bytecode_convert_classt::check_field_exists
bool check_field_exists(const fieldt &field, const irep_idt &qualified_fieldname, const struct_union_typet::componentst &fields) const
Definition: java_bytecode_convert_class.cpp:622
java_string_library_preprocesst::is_known_string_type
bool is_known_string_type(irep_idt class_name)
Check whether a class name is known as a string type.
Definition: java_string_library_preprocess.cpp:1501
java_class_typet::set_is_inner_class
void set_is_inner_class(const bool &is_inner_class)
Definition: java_types.h:338
java_bytecode_parse_treet::classt::signature
optionalt< std::string > signature
Definition: java_bytecode_parse_tree.h:276
java_bytecode_parse_treet::fieldt
Definition: java_bytecode_parse_tree.h:185
java_generic_struct_tag_typet
Class to hold type with generic type arguments, for example java.util.List in either a reference of t...
Definition: java_types.h:857
java_bytecode_parse_treet::classt
Definition: java_bytecode_parse_tree.h:196
java_class_typet::set_abstract
void set_abstract(bool abstract)
marks class abstract
Definition: java_types.h:422
java_generic_class_typet
Class to hold a class with generics, extends the java class type with a vector of java generic type p...
Definition: java_types.h:972
messaget::debug
mstreamt & debug() const
Definition: message.h:429
java_types.h
java_utils.h
messaget::warning
mstreamt & warning() const
Definition: message.h:404
java_bytecode_parse_treet::classt::is_interface
bool is_interface
Definition: java_bytecode_parse_tree.h:217
java_generic_type_from_string
std::vector< typet > java_generic_type_from_string(const std::string &class_name, const std::string &src)
Converts the content of a generic class type into a vector of Java types, that is each type variable ...
Definition: java_types.cpp:749
java_bytecode_convert_classt
Definition: java_bytecode_convert_class.cpp:30
std_expr.h
java_bytecode_parse_treet::classt::is_abstract
bool is_abstract
Definition: java_bytecode_parse_tree.h:213
java_bytecode_parse_treet::classt::inner_name
irep_idt inner_name
Definition: java_bytecode_parse_tree.h:212
java_bytecode_parse_treet::classt::outer_class
irep_idt outer_class
Definition: java_bytecode_parse_tree.h:224
java_bytecode_convert_classt::operator()
void operator()(const java_class_loadert::parse_tree_with_overlayst &parse_trees)
Converts all the class parse trees into a class symbol and adds it to the symbol table.
Definition: java_bytecode_convert_class.cpp:64
java_bytecode_parse_treet::classt::is_anonymous_class
bool is_anonymous_class
Definition: java_bytecode_parse_tree.h:222
java_bytecode_parse_treet::classt::super_class
irep_idt super_class
Definition: java_bytecode_parse_tree.h:212
java_bytecode_convert_classt::max_array_length
const size_t max_array_length
Definition: java_bytecode_convert_class.cpp:109
java_bytecode_convert_class.h