* src/abg-reader.cc (read_context::map_id_and_node): Allow
duplicated class and basic type declarations.
(build_type_decl): Allow duplicated type decls.
(build_qualified_type_decl, build_pointer_type_def)
(build_reference_type_def): As there can be several distinct
duplicated types, compare them by value.
(build_class_decl): There can be duplicated class decls.
* src/abg-writer.cc (write_enum_type_decl): The name of the enum
needs to be xml-escaped.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-reader.cc (build_qualified_type_decl)
(build_pointer_type_def, build_reference_type_def): Consider that
these types can be member types.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (typedef_decl::operator==): Consider two typedefs
with different names to be different.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (build_ir_node_from_die): For the
DW_TAG_subprogram case, bail out early if the current function is
non-public.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-comparison.h
(diff_context::{show_{deleted,changed_added}_{fns,vars}}): Declare
new accessors.
(corpus_diff::context): Declare new getter.
* src/abg-comparison.cc
(diff_context::{show_{deleted,changed_added}_{fns,vars}}): Define
these new accessors.
(corpus_diff::priv::emit_corpus_diff_stats): Define new function.
(corpus_diff::context()): Define new getter.
(corpus_diff::report): Use the new
corpus_diff::priv::emit_corpus_diff_stats to emit diff stats at
the beginning of the report. Conditionalise emitting the
different parts of the reports (changed,deleted,added stuff) on
the values of the new properties that were just added.
* tools/bidiff.cc
(options::{show_{deleted,changed,added}_{fns,vars}): New
properties.
(display_usage, parse_command_line): Update for the newly added
--{changed,deleted,added}-{fns,vars} command line options.
(set_diff_context_from_opts): Define new static function.
(main): Create a diff context, initialize it from the options
(using set_diff_context_from_opts) and pass it to compute_diff.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (class_decl::member_type::traverse): Declare new virtual
function.
(ir_node_visitor::visit): Declare new virtual function
* src/abg-ir.cc (class_decl::member_type::traverse): Implement the
traversal of a member type.
(ir_node_visitor::visit): Provide a default implementation for the
visitor of member type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-fwd.h (as_non_member_class_decl): Declare new overload.
* src/abg-ir.cc (as_non_member_class_decl): Define new overload.
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Add
member functions to the DIE -> IR Node map.
(build_ir_node_from_die): Assert that DW_TAG_subprogram cannot be
for a member function here because getting the scope of the member
function would have constructed the entire class that contains it,
including the member function. Then, calling
build_ir_node_from_die for the DIE of the member function would
find the already IR Node in the DIE -> IR Node map.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (class_decl::enum access_specifier): Give the enumerators
the same values as what the DWARF spec says.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (function_decl::parameter::get_type_name): Add
comment.
(function_decl::parameter::get_type_pretty_representation): New
member fn.
* src/abg-comparison.cc (represent): When representing changed
members, use their pretty representation.
(function_decl_diff::{ensure_lookup_tables_populated, report}): Use the
pretty representation of parameters type.
(typedef_diff::report): Enclose the underlying type in "'".
(corpus_diff::report): Add proper spacing.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc (corpus_diff::report): Emit
information about the number of added/removed/changed
functions. If the report is big, prefix any added
function with '[A]' deleted function with '[B]'. Also,
fix indentation.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-comparison.h (class distinct_diff): Declare new
type.
(compute_diff_for_distinct_kinds): Declare new function.
* src/abg-comparison.cc (distinct_diff::{distinct_diff, first,
second, entities_are_of_distinct_kinds, length, report}): Define
new member functions.
(compute_diff_for_distinct_kinds, try_to_diff_distinct_kinds):
Define new function.
(compute_diff_for_types, compute_diff_for_decls): Support diffing
entities of different kinds.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (class_decl::operator==(const decl_base& other)
const): Bail out early in case of recursive comparison, or if type
hashes are different. Do not try to compute qualified name unless
it's really necessary. The optimizations part of this change were
hinted by profiling.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (build_ir_node_from_die): For the
DW_TAG_subprogram case, if the function has a DW_AT_specification
attribute, build the IR node for the specification DIE instead.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir):
Assert that the result of build_function_decl on a member function
is a method_decl.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc
(class_diff::ensure_lookup_tables_populated): If a member function
has an empty mangling name, use its pretty representation.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc
(class_diff::ensure_lookup_tables_populated): Do not assert that
the same member type cannot be deleted/inserted twice. It
actually can for, pointers, references, typedefs, etc.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc (represent): Remove extra new line after
reporting virtual function number.
(class_diff::report): Do not forget to emit a new line between two
inserted functions.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc
(corpus_diff::priv::ensure_lookup_tables_populated): In a changed
function or variable, do not mix up the new and old value.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-comparison.cc (decls_equal::operator()(const decls_type,
const decls_type) const): Do not crash when of the decl_types is
NULL.
({pointer_diff, reference_diff, enum_diff}::length): Avoid
crashing if the underlying type is NULL.
* abg-ir.cc (function_decl::get_pretty_representation): Avoid
crashing on member functions with empty parameter set.
signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (decl_base::qualified_name_): New member.
(decl_base::get_qualified_name): Cache the qualified name.
(decl_base::get_type): Return a reference on the shared pointer.
(method_type::get_class_type): Likewise.
(class_decl::get_definition_of_declaration): Likewise.
(class_decl::member_type::get_underlying_type): Likewise.
(class_decl::base_spec::get_base_class): Likewise.
* src/abg-ir.cc (decl_base::get_qualified_name): Implement the
caching.
(class_decl::member_type::get_qualified_name): Return a reference
on the shared pointer.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (function_decl::parameter::get_type_name): New
member function.
* src/abg-comparison.cc
(function_decl_diff::ensure_lookup_tables_populated): Use the new
member function above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (d_path_vec::max_d): Avoid using member
functions. This is relevant only when compiling w/o optimization.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (d_path_vec::d_path_vec): Do not
forget to allocate enough data for reverse vectors as well. The
comment of the constructor is accurate.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
accordingly
* include/abg-comparison.h (class diff_context): New class.
(class diff::{ctxt_, reported_once_, currently_reporting_}): New
data members.
(diff::diff): Initialize the new data members above.
(diff::{context, currently_reporting, reported_once}): New
accessors.
(compute_diff, var_diff::var_diff, pointer_diff::pointer_diff)
(reference_diff::reference_diff, qualified_type_diff)
(enum_diff:enum_diff, class_diff::class_diff)
(scope_diff::scope_diff, function_decl_diff::function_decl_diff)
(type_decl_diff::type_decl_diff, typedef_diff::typedef_diff)
(translation_unit_diff::translation_unit_diff, corpus_diff::corpus_diff):
Take an additional pointer to diff_context.
* abg-comparison.cc (diff_context::{has_diff_for,
has_diff_for_types, add_diff}): New methods.
(try_to_diff, compute_diff_for_types, compute_diff_for_decls)
(represent): Take an additional pointer to
diff_context in argument. In the later function, do not re-report
a diff if it has already been reported, or if it's being reported
already.
(var_diff::var_diff, pointer_diff::pointer_diff)
(reference_diff::reference_diff)
(qualified_type_diff::qualified_type_diff, enum_diff::enum_diff)
(class_diff::class_diff, scope_diff::scope_diff)
(function_decl_diff::function_decl_diff, type_decl::type_decl)
(typedef_diff::typedef_diff)
(translation_unit_diff::translation_unit_diff)
(corpus_diff::corpus_diff): Take an additional pointer to
diff_context in argument.
({pointer_diff, qualified_type_diff,
reference_type_diff}::report): do not re-report a diff about the
underlying type if it has already been reported, or if it's being
reported already.
(enum_diff::report): Fix this to properly use the populated lookup
tables.
(compute_diff): take an additional pointer to diff_context in
argument. For the var_decl, pointer_diff reference_type_diff,
qualified_type_diff enum_diff, scope_diff, function_decl_diff,
type_decl_diff and typedef_diff overloads, do not re-build a diff
object, if one exits already. Otherwise, record the new diff
object created so that it can be re-used later.
(enum_diff::ensure_lookup_tables_populated): Fix logic to avoid
one loop.
(class_decl::priv::{deleted_member_functions_,
inserted_member_functions_, changed_member_function_}): New
members to support reporting about member functions changes.
(class_decl::{lookup_tables_empty, clear_lookup_tables, length):
Update for the new additions above.
(class_decl::ensure_lookup_tables_populated): Likewise. Fix to
properly use the lookup tables and also avoid a going through
several loops to compute the changed members.
(class_decl::report): Flip a switch to make the beginning and end
of the reporting, in the context. Also, do not try to report
again, if we were already reporting this diff. Fix quite some
spots to properly use the lookup tables.
(scope_diff::ensure_lookup_tables_populated): Skip decl-only
classes during comparison. Fix some thinkos. Fix logic to avoid a
loop.
(scope_diff::report): Adjust to pass a context to
compute_diff_for_types.
(function_decl_diff::ensure_lookup_tables_populated): Fix logic to
avoid a loop.
(function_decl_diff::report): Adjust call to
compute_diff_for_types to pass the context.
(typedef::report): Avoid re-reporting the diff of the underlying
types, if we are already reporting it.
(corpus_diff::priv::ensure_lookup_tables_populated): Use the
pretty representation of the function rather than its name to key
the maps of deleted and added functions. Fix logic to avoid going
through an additional loop for the changed functions.
(corpus_diff::report): Add a title for removed/added/changed
functions. Fix indentation for added/removed/changed functions.
* include/abg-ir.h (class_decl::comparison_started_): New member
* src/abg-dwarf-reader.cc (is_public_decl): Style fix.
(is_declaration_only_): New static function.
(build_class_type_and_add_to_ir): Create decl-only classes (IR) for
classes flagged as declaration-only in the DWARF.
* src/abg-hash.cc (class_decl:#️⃣:operator()): Do not forget to
include the "is_declaration_only" flag into the hashing.
* src/abg-ir.cc (class_decl::operator==): Look through decl-only
classes to get their definitions and compare the definitions
instead. Avoid comparing member types and fns if the comparison
of this type has already started.
* src/abg-reader.cc (build_class_decl): Set the definition of a
declaration, when we see it.
* tests/data/test-bidiff/test-qual-type0-report.txt: Update.
* tests/data/test-bidiff/test-struct0-report.txt: Likewise.
* tests/data/test-bidiff/test-struct1-report.txt: Likewise.
signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (class_decl::member_type::operator==): Compare the
underlying type of the member type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h ({var_decl, function_decl}::ptr_equal): New
equality functor for pointers to var_decl and function_decl.
({function_decl, var_decl}::hash): Make these hashing functors
public.
* include/abg-hash.cc (struct var_decl::hash, struct
function_decl::hash): Remove these from here. There are now in
the public abg-ir.h.
({var_decl, function_decl}:#️⃣:operator()): Define these here.
* src/abg-corpus.cc (symtab_build_visitor_type::{fns_map,
fn_is_in_map, add_fn_to_map, vars_map, var_is_in_map,
add_var_to_map}): New accessors.
(corpus::priv::build_symbol_table): Avoid duplicated entries in
variables and functions symbols tables.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (compute_diff): Add asserts on for the
length of the shortest edit script during the divide and conquer
part of the diff algorithm.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (end_of_frr_d_path_in_k_plus_delta):
Favour moving left when the two abscissas at the previous steps
are equal.
(compute_diff): Update the length of the shortest edit script when
the size of one of the inputs is zero.
* tests/test-core-diff.cc (in_out_spec): Add a new input to diff
two sequences for regression testing.
* tests/data/test-core-diff/report13.txt: New reference for
the comparison of the new regression test above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (class_decl::member_function::operator==)
(class_decl::member_function::operator==): Do not use the
exception path for dynamic casting. This was near the top of many
profiles.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (insert_decl_into_ir_under_scope)
(build_namespace_decl_and_add_to_ir, build_enum_type)
(build_class_type_and_add_to_ir, build_ir_node_from_die)
(build_ir_node_from_die): Remove.
* tests/data/test-read-dwarf/test0.abi: Update because now type
IDs can be used before they are defined.
* tests/data/test-read-dwarf/test1.abi: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* tools/bilint.cc (options::options): Initialize ...
(options::{diff, bidiff}): ... new members.
(display_usage): Update the display usage string for --diff &
--bidiff options.
(parse_command_line): Support the --diff and --bidiff options.
(main): Require the --diff option to actually diff the emitted
output with input. Make --noout really work for when reading
from dwarf.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-reader.cc (read_context::m_decls_stack): Make this is a
std::deque, rather than a std::stack.
(read_context::{get_id_xml_node_map,
clear_id_xml_node_map, get_xml_node_decl_map,
map_xml_node_to_decl, get_decl_for_xml_node,
clear_xml_node_decl_map, map_id_and_node, get_xml_node_from_id,
get_scope_for_node, build_or_get_type_decl}): New member
functions.
(read_context::{get_cur_decl, push_decl, pop_decl}): Update this
now that the decl stack uses a std::deque.
(read_context::clear_decls_stack): New.
(read_context::get_translation_unit): Use the first decl of the
decl stack, that is most certainly the global scope of the current
translation unit, to get the translation unit.
(read_context::key_type_decl): Take a new flag to force the
re-keying; that is set an id to a new type, even if the id was
already set to a type.
(read_context::push_and_key_type_decl): Assert that a type must
have a declaration.
(handle_*): Make these return the decl_base_sptr resulting from
the parsing of the xml node, rather than just a bool.
(walk_xml_node_to_map_type_ids): New static function.
(read_translation_unit_from_input): Read the abi-instr xml
sub-tree once, just to build an id->xml node map. That way, when a
declaration needs a type what is not yet defined, it can just get
its XML node, build the type from it and use it. Do not forget to
advance the xml reader cursor when the reading of the 'abi-instr'
sub-tree is read. Clear all the new maps we have used for the
current translation unit.
(handle_element_node): Cleanup logic.
(build_namespace_decl): Update the new xml node -> decl map, and
use it to avoid building the same namespace twice.
(build_function_parameter): Do not even try to get the type of a
variadic parameter.
(build_function_decl, build_var_decl): Support types that are defined later.
(build_type_decl): Do not build the same type twice. But there
can be several 'unnamed-enum-underlying-type' node. In that case
just return the previous one.
(build_qualified_type_decl, build_pointer_type_def)
(build_reference_type_def, build_enum_type_decl)
(build_typedef_decl): Support underlying type defined later.
(build_class_decl): Support declaration-only related cases where
we can have several xml nodes with the same id. Update the new
xml node -> IR node maps. Fix member type adding.
(build_type_tparameter, build_non_type_tparameter)
(build_template_tparameter): Support used types defined later.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (class_decl::add_member_class_template): Do not
forget the scope of the member class template itself.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-libxml-utils.cc (unescape_xml_string): Avoid and endless
loop for strings containing an '&' but that are not pre-defined
entities.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (class_decl::declaration_): Make this be a
decl_base_sptr so that it can actually be a
class_decl::member_type which underlying type is a class decl.
(class_decl::{set, get}_earlier_declaration): Take or return a
decl_base_sptr rather than a class_decl_sptr.
* src/abg-ir.cc (class_decl::set_earlier_declaration): Take a
decl_base_sptr rather than a class_decl_sptr.
* src/abg-dwarf-reader.cc (die_class_map_type): Make this map take
decl_base_sptr rather than a class_decl_sptr.
(build_class_type_and_add_to_ir): If the class being currently
built is a member class, do not loose that information after it
has been added to its scope. Also, base types and types of member
variables can be member types and should retain that information.
(build_qualified_type): Likewise, the underlying type of a
qualified type shouldn't loose the information about its
potentially being a member type.
(build_pointer_type_def, build_reference_type, build_typedef_type)
(build_var_decl, build_function_decl): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (class_decl::{member_function_template,
member_class_template}): Make these inherit from decl_base, to
comply with class_decl::member_type.
(class_decl_base_spec::{base_spec, member_type, member_function,
member_function_template, member_class_template}::hash): Declare
these hashing functors in the header here.
(class_decl::{member_base, member_type, data_member,
member_function, member_function_template,
member_class_template}:#️⃣:operator()): define these out of
line here.
(type_base::dynamic_hash::operator()): Update this to hash member
things.
* src/abg-writer.cc (write_qualified_type_def)
(write_pointer_type_def, write_class_decl)
(write_reference_type_def, write_enum_type_decl): Add an overload
that takes the type ID to use in the serialization.
(write_member_type): New implementation.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-fwd.h (as_non_member_class_decl): Declare ...
* src/abg-ir.cc (as_non_member_class_decl): ... this new function.
* include/abg-ir.h (class class_decl::member_type): Add more
comments about member types.
* src/abg-dwarf-reader.cc (get_scope_for_die): Use the new
as_non_member_class_decl here.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>