blob: f584f6b4521aa08769c79475c6846f5d131aeeef [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2024 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
represent(const subrange_diff& diff,
const 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);
bool
maybe_report_diff_for_variable(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);
void
maybe_report_base_class_reordering(const class_diff &d,
ostream &out,
const string &indent);
} // end namespace comparison
} // end namespace abigail
#endif // __ABG_REPORTER_PRIV_H__