Skip to content

Commit 7eb2862

Browse files
authored
Merge pull request #4114 from smowton/smowton/cleanup/generics-on-tags
Move generic information from decorated pointers to decorated tags
2 parents 3aa4152 + 6887863 commit 7eb2862

File tree

3 files changed

+134
-70
lines changed

3 files changed

+134
-70
lines changed

jbmc/src/java_bytecode/java_types.h

Lines changed: 130 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -407,21 +407,21 @@ bool equal_java_types(const typet &type1, const typet &type2);
407407
/// Class to hold a Java generic type parameter (also called type variable),
408408
/// e.g., `T` in `List<T>`.
409409
/// The bound can specify type requirements.
410-
class java_generic_parametert:public reference_typet
410+
class java_generic_parameter_tagt : public struct_tag_typet
411411
{
412412
public:
413413
typedef struct_tag_typet type_variablet;
414414

415-
java_generic_parametert(
415+
java_generic_parameter_tagt(
416416
const irep_idt &_type_var_name,
417417
const struct_tag_typet &_bound)
418-
: reference_typet(java_reference_type(_bound))
418+
: struct_tag_typet(_bound)
419419
{
420420
set(ID_C_java_generic_parameter, true);
421421
type_variables().push_back(struct_tag_typet(_type_var_name));
422422
}
423423

424-
/// \return the type variable as symbol type
424+
/// \return the type variable as struct tag type
425425
const type_variablet &type_variable() const
426426
{
427427
PRECONDITION(!type_variables().empty());
@@ -431,7 +431,7 @@ class java_generic_parametert:public reference_typet
431431
type_variablet &type_variable_ref()
432432
{
433433
PRECONDITION(!type_variables().empty());
434-
return const_cast<type_variablet &>(type_variables().front());
434+
return type_variables().front();
435435
}
436436

437437
const irep_idt get_name() const
@@ -452,13 +452,72 @@ class java_generic_parametert:public reference_typet
452452
}
453453
};
454454

455+
/// Checks whether the type is a java generic parameter/variable, e.g., `T` in
456+
/// `List<T>`.
457+
/// \param type: the type to check
458+
/// \return true if type is a generic Java parameter tag type
459+
inline bool is_java_generic_parameter_tag(const typet &type)
460+
{
461+
return type.get_bool(ID_C_java_generic_parameter);
462+
}
463+
464+
/// \param type: source type
465+
/// \return cast of type into a java_generic_parametert
466+
inline const java_generic_parameter_tagt &
467+
to_java_generic_parameter_tag(const typet &type)
468+
{
469+
PRECONDITION(is_java_generic_parameter_tag(type));
470+
return static_cast<const java_generic_parameter_tagt &>(type);
471+
}
472+
473+
/// \param type: source type
474+
/// \return cast of type into a java_generic_parameter_tag
475+
inline java_generic_parameter_tagt &to_java_generic_parameter_tag(typet &type)
476+
{
477+
PRECONDITION(is_java_generic_parameter_tag(type));
478+
return static_cast<java_generic_parameter_tagt &>(type);
479+
}
480+
481+
/// Reference that points to a java_generic_parameter_tagt. All information is
482+
/// stored on the underlying tag.
483+
class java_generic_parametert : public reference_typet
484+
{
485+
public:
486+
typedef struct_tag_typet type_variablet;
487+
488+
java_generic_parametert(
489+
const irep_idt &_type_var_name,
490+
const struct_tag_typet &_bound)
491+
: reference_typet(java_reference_type(
492+
java_generic_parameter_tagt(_type_var_name, _bound)))
493+
{
494+
}
495+
496+
/// \return the type variable as symbol type
497+
const type_variablet &type_variable() const
498+
{
499+
return to_java_generic_parameter_tag(subtype()).type_variable();
500+
}
501+
502+
type_variablet &type_variable_ref()
503+
{
504+
return to_java_generic_parameter_tag(subtype()).type_variable_ref();
505+
}
506+
507+
const irep_idt get_name() const
508+
{
509+
return to_java_generic_parameter_tag(subtype()).get_name();
510+
}
511+
};
512+
455513
/// Checks whether the type is a java generic parameter/variable, e.g., `T` in
456514
/// `List<T>`.
457515
/// \param type: the type to check
458516
/// \return true if type is a generic Java parameter type
459517
inline bool is_java_generic_parameter(const typet &type)
460518
{
461-
return type.get_bool(ID_C_java_generic_parameter);
519+
return type.id() == ID_pointer &&
520+
is_java_generic_parameter_tag(type.subtype());
462521
}
463522

464523
/// \param type: source type
@@ -493,36 +552,92 @@ inline java_generic_parametert &to_java_generic_parameter(typet &type)
493552
/// - in `HashMap<List<T>, V>` it would contain two elements, the first of
494553
/// type `java_generic_typet` and the second of type
495554
/// `java_generic_parametert`.
555+
class java_generic_struct_tag_typet : public struct_tag_typet
556+
{
557+
public:
558+
typedef std::vector<reference_typet> generic_typest;
559+
560+
explicit java_generic_struct_tag_typet(const struct_tag_typet &type)
561+
: struct_tag_typet(type)
562+
{
563+
set(ID_C_java_generic_symbol, true);
564+
}
565+
566+
java_generic_struct_tag_typet(
567+
const struct_tag_typet &type,
568+
const std::string &base_ref,
569+
const std::string &class_name_prefix);
570+
571+
const generic_typest &generic_types() const
572+
{
573+
return (const generic_typest &)(find(ID_generic_types).get_sub());
574+
}
575+
576+
generic_typest &generic_types()
577+
{
578+
return (generic_typest &)(add(ID_generic_types).get_sub());
579+
}
580+
581+
optionalt<size_t>
582+
generic_type_index(const java_generic_parametert &type) const;
583+
};
584+
585+
/// \param type: the type to check
586+
/// \return true if the type is a symbol type with generics
587+
inline bool is_java_generic_struct_tag_type(const typet &type)
588+
{
589+
return type.get_bool(ID_C_java_generic_symbol);
590+
}
591+
592+
/// \param type: the type to convert
593+
/// \return the converted type
594+
inline const java_generic_struct_tag_typet &
595+
to_java_generic_struct_tag_type(const typet &type)
596+
{
597+
PRECONDITION(is_java_generic_struct_tag_type(type));
598+
return static_cast<const java_generic_struct_tag_typet &>(type);
599+
}
600+
601+
/// \param type: the type to convert
602+
/// \return the converted type
603+
inline java_generic_struct_tag_typet &
604+
to_java_generic_struct_tag_type(typet &type)
605+
{
606+
PRECONDITION(is_java_generic_struct_tag_type(type));
607+
return static_cast<java_generic_struct_tag_typet &>(type);
608+
}
609+
610+
/// Reference that points to a java_generic_struct_tag_typet. All information is
611+
/// stored on the underlying tag.
496612
class java_generic_typet:public reference_typet
497613
{
498614
public:
499-
typedef std::vector<reference_typet> generic_type_argumentst;
615+
typedef java_generic_struct_tag_typet::generic_typest generic_type_argumentst;
500616

501-
explicit java_generic_typet(const typet &_type):
502-
reference_typet(java_reference_type(_type))
617+
explicit java_generic_typet(const typet &_type)
618+
: reference_typet(java_reference_type(
619+
java_generic_struct_tag_typet(to_struct_tag_type(_type))))
503620
{
504-
set(ID_C_java_generic_type, true);
505621
}
506622

507623
/// \return vector of type variables
508624
const generic_type_argumentst &generic_type_arguments() const
509625
{
510-
return (const generic_type_argumentst &)(
511-
find(ID_type_variables).get_sub());
626+
return to_java_generic_struct_tag_type(subtype()).generic_types();
512627
}
513628

514629
/// \return vector of type variables
515630
generic_type_argumentst &generic_type_arguments()
516631
{
517-
return (generic_type_argumentst &)(
518-
add(ID_type_variables).get_sub());
632+
return to_java_generic_struct_tag_type(subtype()).generic_types();
519633
}
520634
};
521635

522636
template <>
523637
inline bool can_cast_type<java_generic_typet>(const typet &type)
524638
{
525-
return is_reference(type) && type.get_bool(ID_C_java_generic_type);
639+
return is_reference(type) &&
640+
type.subtype().get_bool(ID_C_java_generic_symbol);
526641
}
527642

528643
/// \param type: the type to check
@@ -761,58 +876,6 @@ void get_dependencies_from_generic_parameters(
761876
const typet &,
762877
std::set<irep_idt> &);
763878

764-
/// Type for a generic symbol, extends struct_tag_typet with a
765-
/// vector of java generic types.
766-
/// This is used to store the type of generic superclasses and interfaces.
767-
class java_generic_struct_tag_typet : public struct_tag_typet
768-
{
769-
public:
770-
typedef std::vector<reference_typet> generic_typest;
771-
772-
java_generic_struct_tag_typet(
773-
const struct_tag_typet &type,
774-
const std::string &base_ref,
775-
const std::string &class_name_prefix);
776-
777-
const generic_typest &generic_types() const
778-
{
779-
return (const generic_typest &)(find(ID_generic_types).get_sub());
780-
}
781-
782-
generic_typest &generic_types()
783-
{
784-
return (generic_typest &)(add(ID_generic_types).get_sub());
785-
}
786-
787-
optionalt<size_t>
788-
generic_type_index(const java_generic_parametert &type) const;
789-
};
790-
791-
/// \param type: the type to check
792-
/// \return true if the type is a symbol type with generics
793-
inline bool is_java_generic_struct_tag_type(const typet &type)
794-
{
795-
return type.get_bool(ID_C_java_generic_symbol);
796-
}
797-
798-
/// \param type: the type to convert
799-
/// \return the converted type
800-
inline const java_generic_struct_tag_typet &
801-
to_java_generic_struct_tag_type(const typet &type)
802-
{
803-
PRECONDITION(is_java_generic_struct_tag_type(type));
804-
return static_cast<const java_generic_struct_tag_typet &>(type);
805-
}
806-
807-
/// \param type: the type to convert
808-
/// \return the converted type
809-
inline java_generic_struct_tag_typet &
810-
to_java_generic_struct_tag_type(typet &type)
811-
{
812-
PRECONDITION(is_java_generic_struct_tag_type(type));
813-
return static_cast<java_generic_struct_tag_typet &>(type);
814-
}
815-
816879
/// Take a signature string and remove everything in angle brackets allowing for
817880
/// the type to be parsed normally, for example
818881
/// `java.util.HashSet<java.lang.Integer>` will be turned into

jbmc/unit/java-testing-utils/require_type.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ bool require_java_generic_type_argument_expectation(
140140
case require_type::type_argument_kindt::Inst:
141141
{
142142
REQUIRE(!is_java_generic_parameter(type_argument));
143-
REQUIRE(type_argument.subtype() == struct_tag_typet(expected.description));
143+
REQUIRE(
144+
to_struct_tag_type(type_argument.subtype()).get_identifier() ==
145+
expected.description);
144146
return true;
145147
}
146148
}

src/util/irep_ids.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,11 +649,10 @@ IREP_ID_ONE(switch_case_number)
649649
IREP_ID_ONE(java_array_access)
650650
IREP_ID_ONE(java_member_access)
651651
IREP_ID_TWO(C_java_generic_parameter, #java_generic_parameter)
652-
IREP_ID_TWO(C_java_generic_type, #java_generic_type)
653652
IREP_ID_TWO(C_java_generics_class_type, #java_generics_class_type)
654653
IREP_ID_TWO(C_java_implicitly_generic_class_type, #java_implicitly_generic_class_type)
655654
IREP_ID_TWO(C_java_generic_symbol, #java_generic_symbol)
656-
IREP_ID_TWO(generic_types, #generic_types)
655+
IREP_ID_ONE(generic_types)
657656
IREP_ID_TWO(implicit_generic_types, #implicit_generic_types)
658657
IREP_ID_ONE(type_variables)
659658
IREP_ID_TWO(java_lambda_method_handle_index, lambda_method_handle_index)

0 commit comments

Comments
 (0)