1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- Mode: C++ -*- 3 // 4 // Copyright (C) 2013-2020 Red Hat, Inc. 5 // 6 // Author: Dodji Seketeli 7 8 #ifndef __ABG_REPORTER_PRIV_H__ 9 #define __ABG_REPORTER_PRIV_H__ 10 11 #include "abg-comparison.h" 12 #include "abg-reporter.h" 13 14 /// This is a subroutine of a *::report() function. 15 /// 16 /// If the diff about two subjects S1 and S2 was reported earlier or 17 /// is being reported, emit a diagnostic message about this and return 18 /// from the current diff reporting function. 19 /// 20 /// @param S1 the first diff subject to take in account. 21 /// 22 /// @param S2 the second diff subject to take in account. 23 #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(S1, S2) \ 24 do { \ 25 if (diff_context_sptr ctxt = d.context()) \ 26 if (diff_sptr _diff_ = ctxt->get_canonical_diff_for(S1, S2)) \ 27 if (_diff_->currently_reporting() || _diff_->reported_once()) \ 28 { \ 29 if (_diff_->currently_reporting()) \ 30 out << indent << "details are being reported\n"; \ 31 else \ 32 out << indent << "details were reported earlier\n"; \ 33 return; \ 34 } \ 35 } while (false) 36 37 /// This is a subroutine of a *::report() function. 38 /// 39 /// If a given diff was reported earlier or is being reported, emit a 40 /// diagnostic message about this and return from the current diff 41 /// reporting function. 42 /// 43 /// @param S1 the first diff subject to take in account. 44 /// 45 /// @param S2 the second diff subject to take in account. 46 /// 47 /// @param INTRO_TEXT the introductory text that precedes the 48 /// diagnostic. 49 #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(D, INTRO_TEXT) \ 50 do { \ 51 if (diff_sptr _diff_ = d.context()->get_canonical_diff_for(D)) \ 52 if (_diff_->currently_reporting() || _diff_->reported_once()) \ 53 { \ 54 string _name_ = _diff_->first_subject()->get_pretty_representation(); \ 55 if (_diff_->currently_reporting()) \ 56 out << indent << INTRO_TEXT << " '" << _name_ \ 57 << "' changed, as being reported\n"; \ 58 else \ 59 { \ 60 out << indent << INTRO_TEXT << " '" \ 61 << _name_ << "' changed"; \ 62 report_loc_info(D->first_subject(), *d.context(), out); \ 63 out << ", as reported earlier\n"; \ 64 } \ 65 return ; \ 66 } \ 67 } while (false) 68 69 /// This is a subroutine of a *::report() function. 70 /// 71 /// If the diff about two subjects S1 and S2 was reported earlier or 72 /// is being reported, emit a diagnostic message about this and return 73 /// from the current diff reporting function. 74 /// 75 /// 76 /// @param INTRO_TEXT the introductory text that precedes the 77 /// diagnostic. 78 #define RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(S1, S2, INTRO_TEXT) \ 79 do { \ 80 if (diff_sptr _diff_ = d.context()->get_canonical_diff_for(S1, S2)) \ 81 if (_diff_->currently_reporting() || _diff_->reported_once()) \ 82 { \ 83 string _name_ = _diff_->first_subject()->get_pretty_representation(); \ 84 if (_diff_->currently_reporting()) \ 85 out << indent << INTRO_TEXT << " '" << _name_ << "' changed; " \ 86 "details are being reported\n"; \ 87 else \ 88 { \ 89 out << indent << INTRO_TEXT << " '" << _name_ << "' changed"; \ 90 report_loc_info(S1, *d.context(), out); \ 91 out << ", as reported earlier\n"; \ 92 } \ 93 return ; \ 94 } \ 95 } while (false) 96 97 namespace abigail 98 { 99 100 namespace comparison 101 { 102 103 uint64_t 104 convert_bits_to_bytes(size_t bits); 105 106 uint64_t 107 maybe_convert_bits_to_bytes(uint64_t bits, const diff_context& ctxt); 108 109 void 110 emit_num_value(uint64_t value, const diff_context& ctxt, ostream& out); 111 112 void 113 show_offset_or_size(const string& what, 114 uint64_t value, 115 const diff_context& ctxt, 116 ostream& out); 117 118 void 119 show_offset_or_size(uint64_t value, 120 const diff_context& ctxt, 121 ostream& out); 122 123 void 124 show_numerical_change(const string& what, 125 uint64_t old_bits, 126 uint64_t new_bits, 127 const diff_context& ctxt, 128 ostream& out, 129 bool show_bits_or_bytes = true); 130 131 void 132 represent(const diff_context& ctxt, 133 method_decl_sptr mem_fn, 134 ostream& out); 135 136 void 137 represent_data_member(var_decl_sptr d, 138 const diff_context_sptr& ctxt, 139 ostream& out, 140 const string& indent); 141 142 void 143 maybe_show_relative_offset_change(const var_diff_sptr &diff, 144 diff_context& ctxt, 145 ostream& out); 146 147 void 148 maybe_show_relative_size_change(const var_diff_sptr &diff, 149 diff_context& ctxt, 150 ostream& out); 151 152 void 153 represent(const var_diff_sptr &diff, 154 diff_context_sptr ctxt, 155 ostream& out, 156 const string& indent = "", 157 bool local_only = false); 158 159 void 160 report_size_and_alignment_changes(type_or_decl_base_sptr first, 161 type_or_decl_base_sptr second, 162 diff_context_sptr ctxt, 163 ostream& out, 164 const string& indent); 165 166 bool 167 report_loc_info(const type_or_decl_base_sptr& tod, 168 const diff_context& ctxt, 169 ostream &out); 170 171 void 172 report_name_size_and_alignment_changes(decl_base_sptr first, 173 decl_base_sptr second, 174 diff_context_sptr ctxt, 175 ostream& out, 176 const string& indent); 177 178 /// Represent the kind of difference we want report_mem_header() to 179 /// report. 180 enum diff_kind 181 { 182 del_kind, 183 ins_kind, 184 subtype_change_kind, 185 change_kind 186 }; 187 188 void 189 report_mem_header(ostream& out, 190 diff_kind k, 191 const string& section_name, 192 const string& indent); 193 194 void 195 report_mem_header(ostream& out, 196 size_t number, 197 size_t num_filtered, 198 diff_kind k, 199 const string& section_name, 200 const string& indent); 201 202 bool 203 maybe_report_diff_for_member(const decl_base_sptr& decl1, 204 const decl_base_sptr& decl2, 205 const diff_context_sptr& ctxt, 206 ostream& out, 207 const string& indent); 208 209 void 210 maybe_report_diff_for_symbol(const elf_symbol_sptr& symbol1, 211 const elf_symbol_sptr& symbol2, 212 const diff_context_sptr& ctxt, 213 ostream& out, 214 const string& indent); 215 216 void 217 show_linkage_name_and_aliases(ostream& out, 218 const string& indent, 219 const elf_symbol& symbol, 220 const string_elf_symbols_map_type& sym_map); 221 222 void 223 maybe_report_unreachable_type_changes(const corpus_diff& d, 224 const corpus_diff::diff_stats &s, 225 const string& indent, 226 ostream& out); 227 228 void 229 maybe_report_interfaces_impacted_by_diff(const diff *d, 230 ostream &out, 231 const string &indent); 232 233 void 234 maybe_report_interfaces_impacted_by_diff(const diff_sptr &d, 235 ostream &out, 236 const string &indent); 237 238 void 239 maybe_report_data_members_replaced_by_anon_dm(const class_or_union_diff &d, 240 ostream &out, 241 const string indent); 242 243 244 } // end namespace comparison 245 } // end namespace abigail 246 247 #endif // __ABG_REPORTER_PRIV_H__ 248