// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- Mode: C++ -*- // // Copyright (C) 2013-2020 Red Hat, Inc. // // Author: Dodji Seketeli #ifndef __ABG_REPORTER_PRIV_H__ #define __ABG_REPORTER_PRIV_H__ #include "abg-comparison.h" #include "abg-reporter.h" /// This is a subroutine of a *::report() function. /// /// If the diff about two subjects S1 and S2 was reported earlier or /// is being reported, emit a diagnostic message about this and return /// from the current diff reporting function. /// /// @param S1 the first diff subject to take in account. /// /// @param S2 the second diff subject to take in account. #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(S1, S2) \ do { \ if (diff_context_sptr ctxt = d.context()) \ if (diff_sptr _diff_ = ctxt->get_canonical_diff_for(S1, S2)) \ if (_diff_->currently_reporting() || _diff_->reported_once()) \ { \ if (_diff_->currently_reporting()) \ out << indent << "details are being reported\n"; \ else \ out << indent << "details were reported earlier\n"; \ return; \ } \ } while (false) /// This is a subroutine of a *::report() function. /// /// If a given diff was reported earlier or is being reported, emit a /// diagnostic message about this and return from the current diff /// reporting function. /// /// @param S1 the first diff subject to take in account. /// /// @param S2 the second diff subject to take in account. /// /// @param INTRO_TEXT the introductory text that precedes the /// diagnostic. #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(D, INTRO_TEXT) \ do { \ if (diff_sptr _diff_ = d.context()->get_canonical_diff_for(D)) \ if (_diff_->currently_reporting() || _diff_->reported_once()) \ { \ string _name_ = _diff_->first_subject()->get_pretty_representation(); \ if (_diff_->currently_reporting()) \ out << indent << INTRO_TEXT << " '" << _name_ \ << "' changed, as being reported\n"; \ else \ { \ out << indent << INTRO_TEXT << " '" \ << _name_ << "' changed"; \ report_loc_info(D->first_subject(), *d.context(), out); \ out << ", as reported earlier\n"; \ } \ return ; \ } \ } while (false) /// This is a subroutine of a *::report() function. /// /// If the diff about two subjects S1 and S2 was reported earlier or /// is being reported, emit a diagnostic message about this and return /// from the current diff reporting function. /// /// /// @param INTRO_TEXT the introductory text that precedes the /// diagnostic. #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(S1, S2, INTRO_TEXT) \ do { \ if (diff_sptr _diff_ = d.context()->get_canonical_diff_for(S1, S2)) \ if (_diff_->currently_reporting() || _diff_->reported_once()) \ { \ string _name_ = _diff_->first_subject()->get_pretty_representation(); \ if (_diff_->currently_reporting()) \ out << indent << INTRO_TEXT << " '" << _name_ << "' changed; " \ "details are being reported\n"; \ else \ { \ out << indent << INTRO_TEXT << " '" << _name_ << "' changed"; \ report_loc_info(S1, *d.context(), out); \ out << ", as reported earlier\n"; \ } \ return ; \ } \ } while (false) namespace abigail { namespace comparison { uint64_t convert_bits_to_bytes(size_t bits); uint64_t maybe_convert_bits_to_bytes(uint64_t bits, const diff_context& ctxt); void emit_num_value(uint64_t value, const diff_context& ctxt, ostream& out); void show_offset_or_size(const string& what, uint64_t value, const diff_context& ctxt, ostream& out); void show_offset_or_size(uint64_t value, const diff_context& ctxt, ostream& out); void show_numerical_change(const string& what, uint64_t old_bits, uint64_t new_bits, const diff_context& ctxt, ostream& out, bool show_bits_or_bytes = true); void represent(const diff_context& ctxt, method_decl_sptr mem_fn, ostream& out); void represent_data_member(var_decl_sptr d, const diff_context_sptr& ctxt, ostream& out, const string& indent); void maybe_show_relative_offset_change(const var_diff_sptr &diff, diff_context& ctxt, ostream& out); void maybe_show_relative_size_change(const var_diff_sptr &diff, diff_context& ctxt, ostream& out); void represent(const var_diff_sptr &diff, diff_context_sptr ctxt, ostream& out, const string& indent = "", bool local_only = false); void report_size_and_alignment_changes(type_or_decl_base_sptr first, type_or_decl_base_sptr second, diff_context_sptr ctxt, ostream& out, const string& indent); bool report_loc_info(const type_or_decl_base_sptr& tod, const diff_context& ctxt, ostream &out); void report_name_size_and_alignment_changes(decl_base_sptr first, decl_base_sptr second, diff_context_sptr ctxt, ostream& out, const string& indent); /// Represent the kind of difference we want report_mem_header() to /// report. enum diff_kind { del_kind, ins_kind, subtype_change_kind, change_kind }; void report_mem_header(ostream& out, diff_kind k, const string& section_name, const string& indent); void report_mem_header(ostream& out, size_t number, size_t num_filtered, diff_kind k, const string& section_name, const string& indent); bool maybe_report_diff_for_member(const decl_base_sptr& decl1, const decl_base_sptr& decl2, const diff_context_sptr& ctxt, ostream& out, const string& indent); void maybe_report_diff_for_symbol(const elf_symbol_sptr& symbol1, const elf_symbol_sptr& symbol2, const diff_context_sptr& ctxt, ostream& out, const string& indent); void show_linkage_name_and_aliases(ostream& out, const string& indent, const elf_symbol& symbol, const string_elf_symbols_map_type& sym_map); void maybe_report_unreachable_type_changes(const corpus_diff& d, const corpus_diff::diff_stats &s, const string& indent, ostream& out); void maybe_report_interfaces_impacted_by_diff(const diff *d, ostream &out, const string &indent); void maybe_report_interfaces_impacted_by_diff(const diff_sptr &d, ostream &out, const string &indent); void maybe_report_data_members_replaced_by_anon_dm(const class_or_union_diff &d, ostream &out, const string indent); } // end namespace comparison } // end namespace abigail #endif // __ABG_REPORTER_PRIV_H__