15#include <unordered_map>
20#include "abg-internal.h"
23ABG_BEGIN_EXPORT_DECLARATIONS
33ABG_END_EXPORT_DECLARATIONS
45using std::ostringstream;
46using std::unordered_map;
78corpus::exported_decls_builder
87 : priv_(new
priv(fns, vars,
89 vars_suppress_regexps,
92 sym_id_of_fns_to_keep,
93 sym_id_of_vars_to_keep))
117std::unordered_set<const function_decl*>*
120 std::unordered_set<const function_decl*> *fns_for_id =
121 priv_->fn_id_is_in_id_fns_map(fn);
122 if (fns_for_id && fns_for_id->size() > 1)
135{
return priv_->vars_;}
157 const string& fn_id = priv_->get_id(*fn);
160 if (!do_update && priv_->fn_id_is_in_id_fns_map(fn))
164 if (priv_->keep_wrt_id_of_fns_to_keep(fn)
165 && priv_->keep_wrt_regex_of_fns_to_suppress(fn)
166 && priv_->keep_wrt_regex_of_fns_to_keep(fn))
168 priv_->add_fn_to_exported(fn, do_update);
186 if (!var->get_is_in_public_symbol_table())
192 if (priv_->var_is_in_id_vars_map(var))
196 if (priv_->keep_wrt_id_of_vars_to_keep(var)
197 && priv_->keep_wrt_regex_of_vars_to_suppress(var)
198 && priv_->keep_wrt_regex_of_vars_to_keep(var))
200 priv_->add_var_to_exported(var);
221typedef unordered_map<
const var_decl*,
247 string first_name, second_name;
249 if (first_name.empty())
254 if (second_name.empty())
258 if (first_name != second_name)
259 return first_name < second_name;
265 class_or_union_sptr first_scope =
267 class_or_union_sptr second_scope =
279 if (fh && sh && *fh != *sh)
285 return f_cti < s_cti;
289 return first_name < second_name;
312 string first_name, second_name;
314 if (first_name.empty())
322 if (second_name.empty())
325 if (second_name.empty())
333 return first_name < second_name;
337 operator()(
const var_decl_sptr& first,
338 const var_decl_sptr& second)
const
339 {
return operator()(first.get(), second.get());}
344struct comp_elf_symbols_functor
347 operator()(
const elf_symbol& l,
348 const elf_symbol& r)
const
349 {
return l.get_id_string() < r.get_id_string();}
352 operator()(
const elf_symbol_sptr l,
353 const elf_symbol_sptr r)
const
354 {
return operator()(*l, *r);}
380 if (!sorted_fun_symbols)
384 auto filter = symtab_->make_filter();
385 filter.set_functions();
386 sorted_fun_symbols =
elf_symbols(symtab_->begin(filter),
392 return *sorted_fun_symbols;
410 (*fun_symbol_map)[symbol->get_name()].push_back(symbol);
411 (*fun_symbol_map)[symbol->get_id_string()].push_back(symbol);
414 return *fun_symbol_map;
425 if (!sorted_undefined_fun_symbols)
429 auto filter = symtab_->make_filter();
430 filter.set_functions();
431 filter.set_undefined_symbols();
432 filter.set_public_symbols(
false);
434 sorted_undefined_fun_symbols =
435 elf_symbols(symtab_->begin(filter), symtab_->end());
440 return *sorted_undefined_fun_symbols;
453 if (!undefined_fun_symbol_map)
458 (*undefined_fun_symbol_map)[symbol->get_name()].push_back(symbol);
459 (*undefined_fun_symbol_map)[symbol->get_id_string()].push_back(symbol);
462 return *undefined_fun_symbol_map;
478 if (!unrefed_fun_symbols)
483 unordered_map<string, bool> refed_funs;
485 for (
const auto& function : fns)
488 refed_funs[sym->get_id_string()] =
true;
490 a && !a->is_main_symbol(); a = a->get_next_alias())
491 refed_funs[a->get_id_string()] =
true;
494 auto filter = symtab_->make_filter();
495 filter.set_functions();
496 for (
const auto& symbol :
499 const std::string sym_id = symbol->get_id_string();
500 if (refed_funs.find(sym_id) == refed_funs.end())
502 bool keep = sym_id_fns_to_keep.empty();
503 for (
const auto&
id : sym_id_fns_to_keep)
512 unrefed_fun_symbols->push_back(symbol);
517 return *unrefed_fun_symbols;
530 if (!sorted_var_symbols)
534 auto filter = symtab_->make_filter();
535 filter.set_variables();
537 sorted_var_symbols =
elf_symbols(symtab_->begin(filter),
543 return *sorted_var_symbols;
560 (*var_symbol_map)[symbol->get_name()].push_back(symbol);
562 return *var_symbol_map;
573 if (!sorted_undefined_var_symbols)
577 auto filter = symtab_->make_filter();
578 filter.set_variables();
579 filter.set_undefined_symbols();
580 filter.set_public_symbols(
false);
582 sorted_undefined_var_symbols =
583 elf_symbols(symtab_->begin(filter), symtab_->end());
588 return *sorted_undefined_var_symbols;
601 if (!undefined_var_symbol_map)
605 (*undefined_var_symbol_map)[symbol->get_name()].push_back(symbol);
607 return *undefined_var_symbol_map;
623 if (!unrefed_var_symbols)
628 unordered_map<string, bool> refed_vars;
629 for (
const auto& variable : vars)
632 refed_vars[sym->get_id_string()] =
true;
634 a && !a->is_main_symbol(); a = a->get_next_alias())
635 refed_vars[a->get_id_string()] =
true;
638 auto filter = symtab_->make_filter();
639 filter.set_variables();
640 for (
const auto& symbol :
643 const std::string sym_id = symbol->get_id_string();
644 if (refed_vars.find(sym_id) == refed_vars.end())
646 bool keep = sym_id_vars_to_keep.empty();
647 for (
const auto&
id : sym_id_vars_to_keep)
656 unrefed_var_symbols->push_back(symbol);
661 return *unrefed_var_symbols;
679const std::unordered_set<const function_decl*>*
685 auto i = b->priv_->id_fns_map_.find(
id);
686 if (i == b->priv_->id_fns_map_.end())
709 class_or_union_sptr scope =
nullptr, canonical_scope =
nullptr;
725 (canonical_scope && canonical_scope->get_corpus() == scope->get_corpus())
737 canonical_scope->find_member_function(ln);
738 if (!canonical_function)
739 canonical_function = fn;
743 return canonical_function;
753 lock_guard<recursive_mutex> lock(get_mutex());
757 fns_set.insert(get_canonical_function(f));
763 for (
auto& f : fns_set)
770 for (
auto& entry : b->priv_->id_fns_map_)
773 if (entry.second.size() > 1)
775 for (
auto& fn : entry.second)
783 auto canonical_function = get_canonical_function(fn);
784 f_set.insert(canonical_function);
787 entry.second.clear();
788 for (
auto& fn : f_set)
790 auto it = fns_set.find(fn);
791 if (it != fns_set.end())
792 entry.second.insert(*it);
805{do_compute_non_reachable_types_ = f;}
814{
return do_compute_non_reachable_types_.load();}
830{
return types_are_canonicalized_.load();}
839{types_are_canonicalized_ = f;}
853 priv_.reset(
new priv(path, env));
854 init_format_version();
857corpus::~corpus() =
default;
871{
return priv_->do_log;}
890 lock_guard<recursive_mutex> lock(priv_->get_mutex());
895 string_tu_map_type::const_iterator i =
896 priv_->path_tu_map.find(tu->get_absolute_path());
898 priv_->path_tu_map[tu->get_absolute_path()] = tu;
899 i = priv_->path_tu_map.find(tu->get_path());
900 if (i == priv_->path_tu_map.end())
901 priv_->path_tu_map[tu->get_path()] = tu;
903 tu->set_corpus(
this);
911{
return priv_->members;}
922 lock_guard<recursive_mutex> lock(priv_->get_mutex());
923 string_tu_map_type::const_iterator i =
924 priv_->path_tu_map.find(path);
926 if (i == priv_->path_tu_map.end())
938 lock_guard<recursive_mutex> lock(priv_->get_mutex());
939 priv_->members.clear();
947{
return priv_->types_;}
955{
return priv_->types_;}
968{
return priv_->type_per_loc_map_;}
979 lock_guard<recursive_mutex> lock(priv_->get_mutex());
980 return !priv_->reachable_types_from_pub_ifaces_.empty();
994 lock_guard<recursive_mutex> lock(priv_->get_mutex());
995 priv_->reachable_types_from_pub_ifaces_.insert(e);
1001corpus::remove_type_from_reachable_types(
const type_base& t)
1003 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1005 priv_->reachable_types_from_pub_ifaces_.erase(examplar);
1021 if (!priv_->get_compute_non_reachable_types())
1024 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1026 auto it = priv_->reachable_types_from_pub_ifaces_.find(examplar);
1027 if (it == priv_->reachable_types_from_pub_ifaces_.end())
1049 if (!abi->priv_->get_compute_non_reachable_types())
1059 if (group->type_is_reachable_from_public_interfaces(t))
1078 if (!priv_->get_compute_non_reachable_types())
1079 return priv_->non_reachable_types_from_pub_ifaces_;
1081 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1082 if (priv_->non_reachable_types_from_pub_ifaces_.empty())
1087 type_base_sptr t(type_wptr);
1092 priv_->non_reachable_types_from_pub_ifaces_.insert(examplar_type.get());
1096 return priv_->non_reachable_types_from_pub_ifaces_;
1100corpus::get_sorted_types_not_reachable_from_public_interfaces()
const
1102 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1103 if (priv_->sorted_non_reachable_types_from_pub_ifaces_.empty())
1106 priv_->sorted_non_reachable_types_from_pub_ifaces_.push_back(type);
1109 sort(priv_->sorted_non_reachable_types_from_pub_ifaces_.begin(),
1110 priv_->sorted_non_reachable_types_from_pub_ifaces_.end(),
1113 return priv_->sorted_non_reachable_types_from_pub_ifaces_;
1124 reachable_types_marker() =
delete;
1126 reachable_types_marker(corpus& abi)
1129 allow_visiting_already_visited_type_node(
false);
1131 allow_visiting_member_type_nodes(
false);
1146 maybe_record_subtypes_as_reachable(type_base* type,
1147 std::unordered_set<type_base*>& rec_types)
1155 if (rec_types.find(examplar_type) != rec_types.end())
1158 rec_types.insert(examplar_type);
1160 auto abi = examplar_type->get_corpus();
1163 if (
auto d =
is_decl(examplar_type))
1165 for (
auto n : d->get_naming_typedefs())
1166 abi->record_type_as_reachable_from_public_interfaces(*n);
1171 if (
auto u = d->get_underlying_type())
1172 abi->record_type_as_reachable_from_public_interfaces(*u);
1174 else if (
auto typdef =
is_typedef(examplar_type))
1176 if (
auto u = typdef->get_underlying_type())
1177 if (abi->record_type_as_reachable_from_public_interfaces(*u))
1178 maybe_record_subtypes_as_reachable(u.get(), rec_types);
1182 if (
auto p = ptr->get_pointed_to_type())
1183 if (abi->record_type_as_reachable_from_public_interfaces(*p))
1184 maybe_record_subtypes_as_reachable(p.get(), rec_types);
1188 if (
auto p = ref->get_pointed_to_type())
1189 if (abi->record_type_as_reachable_from_public_interfaces(*p))
1190 maybe_record_subtypes_as_reachable(p.get(), rec_types);
1194 if (
auto u = q->get_underlying_type())
1195 if (abi->record_type_as_reachable_from_public_interfaces(*u))
1196 maybe_record_subtypes_as_reachable(u.get(), rec_types);
1200 if (
auto e = a->get_element_type())
1201 if (abi->record_type_as_reachable_from_public_interfaces(*e))
1202 maybe_record_subtypes_as_reachable(e.get(), rec_types);
1204 for (
auto s : a->get_subranges())
1205 if (abi->record_type_as_reachable_from_public_interfaces(*s))
1206 maybe_record_subtypes_as_reachable(s.get(), rec_types);
1210 if (
auto t = fn_type->get_return_type())
1211 if (abi->record_type_as_reachable_from_public_interfaces(*t))
1212 maybe_record_subtypes_as_reachable(t.get(), rec_types);
1214 for (
auto parm : fn_type->get_parameters())
1215 if (auto t = parm->get_type())
1216 if (abi->record_type_as_reachable_from_public_interfaces(*t))
1217 maybe_record_subtypes_as_reachable(t.get(), rec_types);
1221 for (
auto dm : cou->get_data_members())
1222 if (auto t = dm->get_type())
1223 if (abi->record_type_as_reachable_from_public_interfaces(*t))
1224 maybe_record_subtypes_as_reachable(t.get(), rec_types);
1226 for (
auto mf : cou->get_member_functions())
1227 if (auto t = mf->get_type())
1228 if (abi->record_type_as_reachable_from_public_interfaces(*t))
1229 maybe_record_subtypes_as_reachable(t.get(), rec_types);
1244 for (
auto b : klass->get_base_specifiers())
1245 if (auto bc = b->get_base_class())
1246 if (abi->record_type_as_reachable_from_public_interfaces(*bc))
1247 maybe_record_subtypes_as_reachable(bc.get(), rec_types);
1249 for (
auto f : klass->get_virtual_mem_fns())
1250 if (auto t = f->get_type())
1251 if (abi->record_type_as_reachable_from_public_interfaces(*t))
1252 maybe_record_subtypes_as_reachable(t.get(), rec_types);
1256 rec_types.erase(examplar_type);
1265 visit_begin(type_base* type)
1267 if (corpus_.record_type_as_reachable_from_public_interfaces(*type))
1269 std::unordered_set<type_base*> rec_types;
1270 maybe_record_subtypes_as_reachable(type, rec_types);
1277corpus::mark_non_reachable_types()
1279 priv_->set_compute_non_reachable_types(
true);
1281 reachable_types_marker walker(*
this);
1286 const_cast<function_decl*
>(function)->traverse(walker);
1287 if (
auto type =
is_type(function->get_scope()))
1289 type = type->get_canonical_type();
1290 type->traverse(walker);
1297 variable->traverse(walker);
1298 if (
auto type =
is_type(variable->get_scope()))
1300 type = type->get_canonical_type();
1301 type->traverse(walker);
1310 const_cast<function_decl*
>(function)->traverse(walker);
1311 if (
auto type =
is_type(function->get_scope()))
1313 type = type->get_canonical_type();
1314 type->traverse(walker);
1321 variable->traverse(walker);
1322 if (
auto type =
is_type(variable->get_scope()))
1324 type = type->get_canonical_type();
1325 type->traverse(walker);
1342{
return priv_->type_per_loc_map_;}
1350{
return priv_->group;}
1358{
return priv_->group;}
1366 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1376corpus::init_format_version()
1379 (priv_->env.get_config().get_format_major_version_number());
1381 (priv_->env.get_config().get_format_minor_version_number());
1389{
return priv_->origin_;}
1397 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1407{
return priv_->format_major_version_number_;}
1416 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1417 priv_->format_major_version_number_ = maj;
1427{
return priv_->format_minor_version_number_;}
1437 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1438 priv_->format_minor_version_number_ = min;
1451{
return priv_->path;}
1464 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1475const vector<string>&
1477{
return priv_->needed;}
1490 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1491 priv_->needed = needed;
1503{
return priv_->soname;}
1515 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1516 priv_->soname = soname;
1528{
return priv_->architecture_name;}
1540 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1541 priv_->architecture_name = arch;
1556 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1557 bool members_empty =
true;
1558 for (translation_units::const_iterator i = priv_->members.begin(),
1559 e = priv_->members.end();
1562 if (!(*i)->is_empty())
1564 members_empty =
false;
1568 return (members_empty
1570 && priv_->soname.empty()
1571 && priv_->needed.empty()
1572 && priv_->architecture_name.empty()
1584 translation_units::const_iterator i, j;
1603 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1604 priv_->symtab_ = symtab;
1612{
return priv_->symtab_;}
1619{
return priv_->get_fun_symbol_map();}
1629{
return priv_->get_undefined_fun_symbol_map();}
1640{
return priv_->get_sorted_fun_symbols();}
1649{
return priv_->get_sorted_undefined_fun_symbols();}
1660{
return priv_->get_sorted_var_symbols();}
1669{
return priv_->get_sorted_undefined_var_symbols();}
1676{
return priv_->get_var_symbol_map();}
1686{
return priv_->get_undefined_var_symbol_map();}
1706 return it->second[0];
1722 const vector<elf_symbol_sptr>& symbols)
1724 if (version.is_empty())
1729 for (elf_symbols::const_iterator s = symbols.begin();
1732 if ((*s)->get_version().is_empty())
1736 for (elf_symbols::const_iterator s = symbols.begin();
1739 if ((*s)->get_version().is_default())
1744 for (elf_symbols::const_iterator s = symbols.begin();
1747 if ((*s)->get_version().str() == version.
str())
1769 string_elf_symbols_map_type::const_iterator it =
1778 return find_symbol_by_version(version, it->second);
1824 return it->second[0];
1842 string_elf_symbols_map_type::const_iterator it =
1851 return find_symbol_by_version(version, it->second);
1896const std::unordered_set<const function_decl*>*
1898{
return priv_->lookup_functions(
id);}
1914const std::unordered_set<const function_decl*>*
1938const std::unordered_set<const function_decl*>*
1951const std::unordered_set<var_decl_sptr>*
1955 auto i = b->priv_->id_vars_map_.find(
id);
1956 if (i == b->priv_->id_vars_map_.end())
1967const std::unordered_set<var_decl_sptr>*
1991 priv_->remove_redundant_functions();
1995 lock_guard<recursive_mutex> lock(priv_->get_mutex());
1997 std::sort(priv_->fns.begin(), priv_->fns.end(), fc);
1999 priv_->sorted_undefined_fns.clear();
2001 for (
auto& f : priv_->undefined_fns)
2002 priv_->sorted_undefined_fns.push_back(f);
2004 std::sort(priv_->sorted_undefined_fns.begin(),
2005 priv_->sorted_undefined_fns.end(), fc);
2026{
return priv_->vars;}
2035 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2038 std::sort(priv_->vars.begin(), priv_->vars.end(), vc);
2040 priv_->sorted_undefined_vars.clear();
2041 for (
auto& f : priv_->undefined_vars)
2042 priv_->sorted_undefined_vars.push_back(f);
2044 std::sort(priv_->sorted_undefined_vars.begin(),
2045 priv_->sorted_undefined_vars.end(), vc);
2056{
return priv_->undefined_fns;}
2064{
return priv_->undefined_fns;}
2073 if (priv_->sorted_undefined_fns.empty()
2074 && !priv_->undefined_fns.empty())
2079 return priv_->sorted_undefined_fns;
2087 lock_guard<mutex> lock(priv_->undefined_fns_mutex_);
2098{
return priv_->undefined_vars;}
2106{
return priv_->undefined_vars;}
2115 if (priv_->sorted_undefined_vars.empty()
2116 && !priv_->undefined_vars.empty())
2121 return priv_->sorted_undefined_vars;
2129 lock_guard<mutex> lock(priv_->undefined_vars_mutex_);
2144{
return priv_->get_unreferenced_function_symbols();}
2157{
return priv_->get_unreferenced_variable_symbols();}
2166{
return priv_->regex_patterns_fns_to_suppress;}
2173const vector<string>&
2175{
return priv_->regex_patterns_fns_to_suppress;}
2184{
return priv_->regex_patterns_vars_to_suppress;}
2191const vector<string>&
2193{
return priv_->regex_patterns_vars_to_suppress;}
2203{
return priv_->regex_patterns_fns_to_keep;}
2211const vector<string>&
2213{
return priv_->regex_patterns_fns_to_keep;}
2223{
return priv_->sym_id_fns_to_keep;}
2231const vector<string>&
2233{
return priv_->sym_id_fns_to_keep;}
2243{
return priv_->regex_patterns_vars_to_keep;}
2251const vector<string>&
2253{
return priv_->regex_patterns_vars_to_keep;}
2263{
return priv_->sym_id_vars_to_keep;}
2271const vector<string>&
2273{
return priv_->sym_id_vars_to_keep;}
2281 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2282 string sym_name, sym_version;
2286 for (
auto f = priv_->fns.begin(); f != priv_->fns.end(); ++f)
2288 if (b->priv_->keep_wrt_id_of_fns_to_keep(*f)
2289 && b->priv_->keep_wrt_regex_of_fns_to_suppress(*f)
2290 && b->priv_->keep_wrt_regex_of_fns_to_keep(*f))
2291 fns_to_keep.push_back(*f);
2293 priv_->fns = fns_to_keep;
2296 for (
auto v = priv_->vars.begin(); v != priv_->vars.end(); ++v)
2298 if (b->priv_->keep_wrt_id_of_vars_to_keep(*v)
2299 && b->priv_->keep_wrt_regex_of_vars_to_suppress(*v)
2300 && b->priv_->keep_wrt_regex_of_vars_to_keep(*v))
2301 vars_to_keep.push_back(*v);
2303 priv_->vars = vars_to_keep;
2320 lock_guard<mutex> lock(priv_->exported_decls_builder_mutex);
2321 if (!priv_->exported_decls_builder)
2323 priv_->exported_decls_builder.reset
2326 priv_->regex_patterns_fns_to_suppress,
2327 priv_->regex_patterns_vars_to_suppress,
2328 priv_->regex_patterns_fns_to_keep,
2329 priv_->regex_patterns_vars_to_keep,
2330 priv_->sym_id_fns_to_keep,
2331 priv_->sym_id_vars_to_keep));
2334 return priv_->exported_decls_builder;
2398struct corpus_group::priv
2400 recursive_mutex mutex;
2401 std::set<string> corpora_paths;
2402 corpora_type corpora;
2403 istring_function_decl_ptr_map_type fns_map;
2405 istring_var_decl_ptr_map_type vars_map;
2411 unordered_map<string, elf_symbol_sptr> unrefed_fun_symbol_map;
2413 bool unrefed_fun_symbols_built;
2414 unordered_map<string, elf_symbol_sptr> unrefed_var_symbol_map;
2416 bool unrefed_var_symbols_built;
2417 unordered_set<interned_string, hash_interned_string> pub_type_pretty_reprs_;
2420 : unrefed_fun_symbols_built(),
2421 unrefed_var_symbols_built()
2431 lock_guard<recursive_mutex> lock(get_mutex());
2432 for (elf_symbols::const_iterator e = syms.begin();
2436 string sym_id = (*e)->get_id_string();
2437 unordered_map<string, elf_symbol_sptr>::const_iterator j =
2438 unrefed_fun_symbol_map.find(sym_id);
2439 if (j != unrefed_fun_symbol_map.end())
2442 unrefed_fun_symbol_map[sym_id] = *e;
2443 unrefed_fun_symbols.push_back(*e);
2445 unrefed_fun_symbols_built =
true;
2455 lock_guard<recursive_mutex> lock(get_mutex());
2456 for (elf_symbols::const_iterator e = syms.begin();
2460 string sym_id = (*e)->get_id_string();
2461 unordered_map<string, elf_symbol_sptr>::const_iterator j =
2462 unrefed_var_symbol_map.find(sym_id);
2463 if (j != unrefed_var_symbol_map.end())
2466 unrefed_var_symbol_map[sym_id] = *e;
2467 unrefed_var_symbols.push_back(*e);
2469 unrefed_var_symbols_built =
true;
2482corpus_group::corpus_group(
const environment& env,
const string& path =
"")
2483 :
corpus(env, path), priv_(new priv)
2499 if (!corp->get_path().empty()
2503 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2507 corp_arch = corp->get_architecture_name();
2508 if (cur_arch.empty())
2510 else if (cur_arch != corp_arch)
2512 std::cerr <<
"corpus '" << corp->get_path() <<
"'"
2513 <<
" has architecture '" << corp_arch <<
"'"
2514 <<
" but expected '" << cur_arch <<
"'\n";
2518 priv_->corpora.push_back(corp);
2519 corp->set_group(
this);
2520 priv_->corpora_paths.insert(corp->get_path());
2529 for (
auto& t : corp->priv_->reachable_types_from_pub_ifaces_)
2542 if (priv_->corpora_paths.find(path) != priv_->corpora_paths.end())
2551const corpus_group::corpora_type&
2553{
return priv_->corpora;}
2570 return corpus_sptr();
2592 if (priv_->fns.empty())
2594 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2595 for (corpora_type::const_iterator i =
get_corpora().begin();
2600 for (corpus::functions::const_iterator f = c->get_functions().begin();
2601 f != c->get_functions().end();
2605 istring_function_decl_ptr_map_type::const_iterator j =
2606 priv_->fns_map.find(fid);
2608 if (j != priv_->fns_map.end())
2612 priv_->fns_map[fid] = *f;
2614 priv_->fns.push_back(*f);
2633 if (priv_->vars.empty())
2635 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2636 for (corpora_type::const_iterator i =
get_corpora().begin();
2641 for (corpus::variables::const_iterator v = c->get_variables().begin();
2642 v != c->get_variables().end();
2646 istring_var_decl_ptr_map_type::const_iterator j =
2647 priv_->vars_map.find(vid);
2649 if (j != priv_->vars_map.end())
2653 priv_->vars_map[vid] = *v;
2655 priv_->vars.push_back(*v);
2670 if (priv_->var_symbol_map.empty())
2672 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2673 for (corpora_type::const_iterator i =
get_corpora().begin();
2676 priv_->var_symbol_map.insert((*i)->get_var_symbol_map().begin(),
2677 (*i)->get_var_symbol_map().end());
2679 return priv_->var_symbol_map;
2689 if (priv_->fun_symbol_map.empty())
2691 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2692 for (corpora_type::const_iterator i =
get_corpora().begin();
2695 priv_->fun_symbol_map.insert((*i)->get_fun_symbol_map().begin(),
2696 (*i)->get_fun_symbol_map().end());
2699 return priv_->fun_symbol_map;
2709 if (priv_->sorted_fun_symbols.empty()
2712 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2713 for (corpora_type::const_iterator i =
get_corpora().begin();
2718 for (string_elf_symbols_map_type::const_iterator j =
2719 c->get_fun_symbol_map().begin();
2720 j != c->get_fun_symbol_map().begin();
2722 priv_->sorted_fun_symbols.insert(priv_->sorted_fun_symbols.end(),
2726 comp_elf_symbols_functor comp;
2727 std::sort(priv_->sorted_fun_symbols.begin(),
2728 priv_->sorted_fun_symbols.end(),
2732 return priv_->sorted_fun_symbols;
2742 if (priv_->sorted_var_symbols.empty()
2745 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2746 for (corpora_type::const_iterator i =
get_corpora().begin();
2751 for (string_elf_symbols_map_type::const_iterator j =
2752 c->get_var_symbol_map().begin();
2753 j != c->get_var_symbol_map().begin();
2755 priv_->sorted_var_symbols.insert(priv_->sorted_var_symbols.end(),
2759 comp_elf_symbols_functor comp;
2760 std::sort(priv_->sorted_var_symbols.begin(),
2761 priv_->sorted_var_symbols.end(),
2765 return priv_->sorted_var_symbols;
2782 if (!priv_->unrefed_fun_symbols_built)
2783 if (priv_->unrefed_fun_symbols.empty())
2785 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2786 for (corpora_type::const_iterator i =
get_corpora().begin();
2791 for (elf_symbols::const_iterator e =
2792 c->get_unreferenced_function_symbols().begin();
2793 e != c->get_unreferenced_function_symbols().end();
2796 string sym_id = (*e)->get_id_string();
2797 unordered_map<string, elf_symbol_sptr>::const_iterator j =
2798 priv_->unrefed_fun_symbol_map.find(sym_id);
2799 if (j != priv_->unrefed_fun_symbol_map.end())
2802 priv_->unrefed_fun_symbol_map[sym_id] = *e;
2803 priv_->unrefed_fun_symbols.push_back(*e);
2806 priv_->unrefed_fun_symbols_built =
true;
2809 return priv_->unrefed_fun_symbols;
2826 if (!priv_->unrefed_var_symbols_built)
2827 if (priv_->unrefed_var_symbols.empty())
2829 lock_guard<recursive_mutex> lock(priv_->get_mutex());
2830 for (corpora_type::const_iterator i =
get_corpora().begin();
2835 for (elf_symbols::const_iterator e =
2836 c->get_unreferenced_variable_symbols().begin();
2837 e != c->get_unreferenced_variable_symbols().end();
2840 string sym_id = (*e)->get_id_string();
2841 unordered_map<string, elf_symbol_sptr>::const_iterator j =
2842 priv_->unrefed_var_symbol_map.find(sym_id);
2843 if (j != priv_->unrefed_var_symbol_map.end())
2846 priv_->unrefed_var_symbol_map[sym_id] = *e;
2847 priv_->unrefed_var_symbols.push_back(*e);
2850 priv_->unrefed_var_symbols_built =
true;
2853 return priv_->unrefed_var_symbols;
2874const std::unordered_set<const function_decl*>*
2878 if (
auto fns = corp->lookup_functions(
id))
2902const std::unordered_set<const function_decl*>*
2906 if (
const auto& fns = corp->lookup_functions(
id))
2922const std::unordered_set<var_decl_sptr>*
2926 if (
const auto& vars = corp->lookup_variables(
id))
2942const std::unordered_set<var_decl_sptr>*
2946 if (
const auto& vars = corp->lookup_variables(
id))
2960{
return std::dynamic_pointer_cast<corpus_group>(
corpus);}
2965dumptypes(
const vector<type_base_wptr>& types,
2966 const char* output_file,
2973 std::ofstream of(output_file);
2974 if (of.fail() ||!of.is_open())
2978 for (
auto& t : types)
2981 repr = type->get_pretty_representation();
2982 std::ostringstream os;
2983 os <<
"'" << repr <<
"'";
2986 os <<
":" << decl->get_location().expand();
2992 of << os.str() <<
"\n";
The private data and functions of the abigail::ir::corpus type.
std::shared_ptr< symtab > symtab_sptr
Convenience typedef for a shared pointer to a symtab.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Types of the main internal representation of libabigail.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
Utilities to ease the wrapping of C types into std::shared_ptr.
This contains the declarations for the symtab reader.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
The type of the private data of corpus::exported_decls_builder type.
Abstracts the building of the set of exported variables and functions.
const functions & exported_functions() const
Getter for the reference to the vector of exported functions. This vector is shared with with the cor...
std::unordered_set< const function_decl * > * fn_id_maps_to_several_fns(const function_decl *)
Test if a given function ID maps to several functions in the same corpus.
bool maybe_add_fn_to_exported_fns(function_decl *, bool do_update=false)
Consider at all the tunables that control wether a function should be added to the set of exported fu...
bool maybe_add_var_to_exported_vars(const var_decl_sptr &)
Consider at all the tunables that control wether a variable should be added to the set of exported va...
const variables & exported_variables() const
Getter for the reference to the vector of exported variables. This vector is shared with with the cor...
Abstraction of a group of corpora.
virtual const elf_symbols & get_sorted_var_symbols() const
Get a sorted vector of the symbols of the variables exported by the corpora of the current group.
bool has_corpus(const string &)
Test if a corpus of a given path has been added to the group.
const corpora_type & get_corpora() const
Getter of the vector of corpora held by the current corpus_group.
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Get the symbols of the global variables exported by the corpora of the current corpus_group.
virtual const elf_symbols & get_sorted_fun_symbols() const
Get a sorted vector of the symbols of the functions exported by the corpora of the current group.
virtual const std::unordered_set< const function_decl * > * lookup_functions(const interned_string &id) const
Lookup the function which has a given function ID.
virtual bool is_empty() const
Test if the current corpus group is empty.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Get the symbols of the global functions exported by the corpora of the current corpus_group.
const corpus_sptr get_main_corpus() const
Getter of the first corpus added to this Group.
virtual const elf_symbols & get_unreferenced_function_symbols() const
Get the set of function symbols not referenced by any debug info, from all the corpora of the current...
virtual const elf_symbols & get_unreferenced_variable_symbols() const
Get the set of variable symbols not referenced by any debug info, from all the corpora of the current...
virtual const std::unordered_set< var_decl_sptr > * lookup_variables(const interned_string &id) const
Lookup the exported variables which all have a given variable ID.
virtual const corpus::variables & get_variables() const
Get the global variables exported by the corpora of the current corpus group.
virtual ~corpus_group()
Desctructor of the corpus_group type.
void add_corpus(const corpus_sptr &)
Add a new corpus to the current instance of corpus_group.
virtual const corpus::functions & get_functions() const
Get the functions exported by the corpora of the current corpus group.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
const elf_symbol_sptr lookup_function_symbol(const string &n) const
Look in the function symbols map for a symbol with a given name.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
void sort_functions()
Sort the set of functions exported by this corpus.
void set_soname(const string &)
Setter for the soname property of the corpus.
const functions_set & get_undefined_functions() const
Getter of the undefined functions of the corpus.
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
exported_decls_builder_sptr get_exported_decls_builder() const
Getter for the object that is responsible for determining what decls ought to be in the set of export...
void maybe_drop_some_exported_decls()
After the set of exported functions and variables have been built, consider all the tunables that con...
const string_elf_symbols_map_type & get_undefined_var_symbol_map() const
Getter for the map of variable symbols that are undefined in this corpus.
void add(const translation_unit_sptr &)
Add a translation unit to the current ABI Corpus.
std::unordered_set< const function_decl * > functions_set
Convenience typedef for std::unordered_set<const function_decl*>
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
const variables & get_sorted_undefined_variables() const
Getter of the sorted vector of undefined variables of the corpus.
const elf_symbol_sptr lookup_variable_symbol(const string &n) const
Look in the variable symbols map for a symbol with a given name.
vector< var_decl_sptr > variables
Convenience typedef for std::vector<abigail::ir::var_decl*>
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
const string & get_soname()
Getter for the soname property of the corpus.
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
const symtab_reader::symtab_sptr & get_symtab() const
Getter for the symtab object.
virtual const std::unordered_set< const function_decl * > * lookup_functions(const interned_string &id) const
Lookup the function which has a given function ID.
const variables_set & get_undefined_variables() const
Getter of the undefined variables of the corpus.
origin get_origin() const
Getter for the origin of the corpus.
virtual bool is_empty() const
Tests if the corpus is empty from an ABI surface perspective. I.e. if all of these criteria are true:
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
vector< string > & get_sym_ids_of_vars_to_keep()
Getter for the vector of variable symbol IDs to keep.
bool do_log() const
Test if logging was requested.
const translation_unit_sptr find_translation_unit(const string &path) const
Find the translation unit that has a given path.
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
string & get_path() const
Get the file path associated to the corpus file.
const string_elf_symbols_map_type & get_undefined_fun_symbol_map() const
Getter for the map of function symbols that are undefined in this corpus.
void set_origin(origin)
Setter for the origin of the corpus.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
bool operator==(const corpus &) const
Compare the current corpus against another one.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
void drop_translation_units()
Erase the translation units contained in this in-memory object.
void sort_variables()
Sort the set of variables exported by this corpus.
vector< string > & get_regex_patterns_of_vars_to_keep()
Accessor for the regex patterns describing the variables to keep into the public decl table....
vector< string > & get_regex_patterns_of_vars_to_suppress()
Accessor for the regex patterns describing the variables to drop from the public decl table.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
vector< string > & get_regex_patterns_of_fns_to_suppress()
Accessor for the regex patterns describing the functions to drop from the public decl table.
const functions & get_sorted_undefined_functions() const
Getter of the sorted vector of undefined functions of the corpus.
const canonical_type_ptr_set_type & get_types_not_reachable_from_public_interfaces() const
Getter of a sorted vector of the types that are *NOT* reachable from public interfaces.
virtual const elf_symbols & get_unreferenced_function_symbols() const
Getter of the set of function symbols that are not referenced by any function exported by the current...
void set_path(const string &)
Set the file path associated to the corpus file.
virtual const elf_symbols & get_unreferenced_variable_symbols() const
Getter of the set of variable symbols that are not referenced by any variable exported by the current...
bool type_is_reachable_from_public_interfaces(const type_base &) const
Test if a type is reachable from public interfaces (global functions and variables).
virtual bool recording_types_reachable_from_public_interface_supported()
Test if the recording of reachable types (and thus, indirectly, the recording of non-reachable types)...
virtual const std::unordered_set< var_decl_sptr > * lookup_variables(const interned_string &id) const
Lookup the exported variables which all have a given variable ID.
virtual const variables & get_variables() const
Return the public decl table of the global variables of the current corpus.
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
void set_needed(const vector< string > &)
Setter of the needed property of the corpus.
vector< string > & get_sym_ids_of_fns_to_keep()
Getter for the vector of function symbol IDs to keep.
vector< const function_decl * > functions
Convenience typedef for std::vector<abigail::ir::function_decl*>
void set_architecture_name(const string &)
Setter for the architecture name of the corpus.
bool record_type_as_reachable_from_public_interfaces(const type_base &)
Record a type as being reachable from public interfaces (global functions and variables).
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
void set_format_major_version_number(const string &)
Setter of the major version number of the abixml serialization format.
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
vector< string > strings_type
A convenience typedef for std::vector<string>.
std::unordered_set< var_decl_sptr > variables_set
Convenience typedef for std::unordered_set<const var_decl*>.
const environment & get_environment() const
Getter of the enviroment of the corpus.
vector< string > & get_regex_patterns_of_fns_to_keep()
Accessor for the regex patterns describing the functions to keep into the public decl table....
void set_format_minor_version_number(const string &)
Setter of the minor version number of the abixml serialization format.
string & get_format_minor_version_number() const
Getter of the minor version number of the abixml serialization format.
virtual const functions & get_functions() const
Return the functions public decl table of the current corpus.
string & get_format_major_version_number() const
Getter of the major version number of the abixml serialization format.
virtual const interned_string & get_name() const
Getter for the name of the current decl.
scope_decl_sptr get_scope() const
Return the type containing the current decl, if any.
const interned_string & get_linkage_name() const
Getter for the mangled name.
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
The abstraction of the version of an ELF symbol.
const string & str() const
Getter for the version name.
Abstraction of an elf symbol.
const string & get_name() const
Getter for the name of the elf_symbol.
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Abstraction for a function declaration.
The base class for the visitor type hierarchy used for traversing a translation unit.
An abstraction helper for type declarations.
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
const vector< type_base_wptr > & get_types_sorted() const
Getter of all types types sorted by their pretty representation.
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Abstracts a variable declaration.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return the pretty representation of this variable.
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
type_base_sptr get_exemplar_type(type_base_sptr type)
For a given type, return its exemplar type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
unordered_map< string, const function_decl * > str_fn_ptr_map_type
Convenience typedef for a hash map of string and pointer to function_decl.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
unordered_map< const function_decl *, bool, function_decl::hash, function_decl::ptr_equal > fn_ptr_map_type
Convenience typedef for a hash map of pointer to function_decl and boolean.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
unordered_map< const var_decl *, bool, var_decl::hash, var_decl::ptr_equal > var_ptr_map_type
Convenience typedef for a hash map of pointer to var_decl and boolean.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
vector< type_base * > type_base_ptrs_type
Helper typedef for a vector of pointer to type_base.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
std::set< translation_unit_sptr, shared_translation_unit_comp > translation_units
Convenience typedef for an ordered set of translation_unit_sptr.
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
unordered_set< const function_decl *, c11d_decl_hasher< function_decl >, c11d_decl_eq< function_decl > > functions_set_type
A set of hashed function decls. The hash value is the canonical type of the function....
unordered_set< type_base *, canonical_type_hash > canonical_type_ptr_set_type
Helper typedef for an unordered set of type_base* which uses pointer value to tell its members appart...
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Toplevel namespace for libabigail.
A functor to compare instances of var_decl base on their qualified names.
The private data of the corpus type.
const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
bool types_are_canonicalized() const
Getter of whether the types reachable from this ABI are canonicalized or not.
const string_elf_symbols_map_type & get_undefined_var_symbol_map() const
Return a map from name to undefined variable symbol for this corpus.
const string_elf_symbols_map_type & get_var_symbol_map() const
Return a map from name to variable symbol for this corpus.
const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
bool get_compute_non_reachable_types() const
Get the "compute-non-reachable-types' property of the corpus. When it's set to true,...
const std::unordered_set< const function_decl * > * lookup_functions(const interned_string &id)
Lookup the function which has a given function ID.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
const string_elf_symbols_map_type & get_undefined_fun_symbol_map() const
Return a map from name to undefined function symbol for this corpus.
const string_elf_symbols_map_type & get_fun_symbol_map() const
Return a map from name to function symbol for this corpus.
void remove_redundant_functions()
Remove redundant functions from the "fns" vector.
const elf_symbols & get_unreferenced_function_symbols() const
Return a list of symbols that are not referenced by any function of corpus::get_functions().
const elf_symbols & get_unreferenced_variable_symbols() const
Return a list of symbols that are not referenced by any variable of corpus::get_variables().
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
~priv()
Destructor of the corpus::priv type.
void set_compute_non_reachable_types(bool f)
Set the "compute-non-reachable-types' property of the corpus. When it's set to true,...
recursive_mutex & get_mutex()
Getter of the recursive mutex of this corpus.
Equality functor for instances of function_decl.
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A comparison functor for pointers to var_decl.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.