libabigail
abg-corpus.cc
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright (C) 2013-2023 Red Hat, Inc.
5 
6 /// @file
7 
8 #include "config.h"
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <cstdio>
13 #include <cstring>
14 #include <stdexcept>
15 #include <unordered_map>
16 #include <set>
17 
18 #include "abg-internal.h"
19 
20 // <headers defining libabigail's API go under here>
21 ABG_BEGIN_EXPORT_DECLARATIONS
22 
23 #include "abg-corpus.h"
24 #include "abg-ir.h"
25 #include "abg-reader.h"
26 #include "abg-sptr-utils.h"
27 #include "abg-symtab-reader.h"
28 #include "abg-tools-utils.h"
29 #include "abg-writer.h"
30 
31 ABG_END_EXPORT_DECLARATIONS
32 // </headers defining libabigail's API>
33 
34 #include "abg-corpus-priv.h"
35 #include "abg-ir-priv.h"
36 
37 namespace abigail
38 {
39 
40 namespace ir
41 {
42 
43 using std::ostringstream;
44 using std::unordered_map;
45 using std::list;
46 using std::vector;
47 
49 
50 /// Constructor of @ref corpus::exported_decls_builder.
51 ///
52 /// @param fns a reference to the vector of exported functions.
53 ///
54 /// @param vars a reference to the vector of exported variables.
55 ///
56 /// @param fns_suppress_regexps the regular expressions that designate
57 /// the functions to suppress from the exported functions set.
58 ///
59 /// @param vars_suppress_regexps the regular expressions that designate
60 /// the variables to suppress from the exported variables set.
61 ///
62 /// @param fns_keep_regexps the regular expressions that designate the
63 /// functions to keep in the exported functions set.
64 ///
65 /// @param fns_keep_regexps the regular expressions that designate the
66 /// functions to keep in the exported functions set.
67 ///
68 /// @param vars_keep_regexps the regular expressions that designate
69 /// the variables to keep in the exported variables set.
70 ///
71 /// @param sym_id_of_fns_to_keep the IDs of the functions to keep in
72 /// the exported functions set.
73 ///
74 /// @param sym_id_of_vars_to_keep the IDs of the variables to keep in
75 /// the exported variables set.
76 corpus::exported_decls_builder
77 ::exported_decls_builder(functions& fns,
78  variables& vars,
79  strings_type& fns_suppress_regexps,
80  strings_type& vars_suppress_regexps,
81  strings_type& fns_keep_regexps,
82  strings_type& vars_keep_regexps,
83  strings_type& sym_id_of_fns_to_keep,
84  strings_type& sym_id_of_vars_to_keep)
85  : priv_(new priv(fns, vars,
86  fns_suppress_regexps,
87  vars_suppress_regexps,
88  fns_keep_regexps,
89  vars_keep_regexps,
90  sym_id_of_fns_to_keep,
91  sym_id_of_vars_to_keep))
92 {
93 }
94 
95 /// Getter for the reference to the vector of exported functions.
96 /// This vector is shared with with the @ref corpus. It's where the
97 /// set of exported function is ultimately stored.
98 ///
99 /// @return a reference to the vector of exported functions.
100 const corpus::functions&
102 {return priv_->fns_;}
103 
104 /// Getter for the reference to the vector of exported functions.
105 /// This vector is shared with with the @ref corpus. It's where the
106 /// set of exported function is ultimately stored.
107 ///
108 /// @return a reference to the vector of exported functions.
111 {return priv_->fns_;}
112 
113 /// Test if a given function ID maps to several functions in the same corpus.
114 ///
115 /// The magic of ELF symbol aliases makes it possible for an ELF
116 /// symbol alias to designate several different functions. This
117 /// function tests if the ELF symbol of a given function has a aliases
118 /// that designates another function or not.
119 ///
120 /// @param fn the function to consider.
121 ///
122 /// @return the set of functions designated by the ELF symbol of @p
123 /// fn, or nullptr if the function ID maps to just @p fn.
124 std::unordered_set<function_decl*>*
126 {
127  std::unordered_set<function_decl*> *fns_for_id =
128  priv_->fn_id_is_in_id_fns_map(fn);
129  if (fns_for_id && fns_for_id->size() > 1)
130  return fns_for_id;
131 
132  return nullptr;
133 }
134 
135 /// Getter for the reference to the vector of exported variables.
136 /// This vector is shared with with the @ref corpus. It's where the
137 /// set of exported variable is ultimately stored.
138 ///
139 /// @return a reference to the vector of exported variables.
140 const corpus::variables&
142 {return priv_->vars_;}
143 
144 /// Getter for the reference to the vector of exported variables.
145 /// This vector is shared with with the @ref corpus. It's where the
146 /// set of exported variable is ultimately stored.
147 ///
148 /// @return a reference to the vector of exported variables.
151 {return priv_->vars_;}
152 
153 /// Consider at all the tunables that control wether a function should
154 /// be added to the set of exported function and if it fits in, add
155 /// the function to that set.
156 ///
157 /// @param fn the function to add the set of exported functions.
158 void
160 {
162  return;
163 
164  const string& fn_id = priv_->get_id(*fn);
165  ABG_ASSERT(!fn_id.empty());
166 
167  if (priv_->fn_is_in_id_fns_map(fn))
168  return;
169 
170  if (priv_->keep_wrt_id_of_fns_to_keep(fn)
171  && priv_->keep_wrt_regex_of_fns_to_suppress(fn)
172  && priv_->keep_wrt_regex_of_fns_to_keep(fn))
173  priv_->add_fn_to_exported(fn);
174 }
175 
176 /// Consider at all the tunables that control wether a variable should
177 /// be added to the set of exported variable and if it fits in, add
178 /// the variable to that set.
179 ///
180 /// @param fn the variable to add the set of exported variables.
181 void
183 {
184  if (!var->get_is_in_public_symbol_table())
185  return;
186 
187  const string& var_id = priv_->get_id(*var);
188  ABG_ASSERT(!var_id.empty());
189 
190  if (priv_->var_id_is_in_id_var_map(var_id))
191  return;
192 
193  if (priv_->keep_wrt_id_of_vars_to_keep(var)
194  && priv_->keep_wrt_regex_of_vars_to_suppress(var)
195  && priv_->keep_wrt_regex_of_vars_to_keep(var))
196  priv_->add_var_to_exported(var);
197 }
198 
199 // </corpus::exported_decls_builder>
200 
201 /// Convenience typedef for a hash map of pointer to function_decl and
202 /// boolean.
203 typedef unordered_map<const function_decl*,
204  bool,
207 
208 /// Convenience typedef for a hash map of string and pointer to
209 /// function_decl.
210 typedef unordered_map<string, const function_decl*> str_fn_ptr_map_type;
211 
212 /// Convenience typedef for a hash map of pointer to var_decl and boolean.
213 typedef unordered_map<const var_decl*,
214  bool,
217 
218 /// This is a comparison functor for comparing pointers to @ref
219 /// function_decl.
220 struct func_comp
221 {
222  /// The comparisong operator for pointers to @ref function_decl. It
223  /// performs a string comparison of the mangled names of the
224  /// functions. If the functions don't have mangled names, it
225  /// compares their names instead.
226  ///
227  /// @param first the first function to consider in the comparison.
228  ///
229  /// @param second the second function to consider in the comparison.
230  ///
231  /// @return true if the (mangled) name of the first function is less
232  /// than the (mangled)name of the second one, false otherwise.
233  bool
234  operator()(const function_decl* first,
235  const function_decl* second) const
236  {
237  ABG_ASSERT(first != 0 && second != 0);
238 
239  string first_name, second_name;
240  first_name = first->get_linkage_name();
241  if (first_name.empty())
242  first_name = first->get_name();
243  ABG_ASSERT(!first_name.empty());
244 
245  second_name = second->get_linkage_name();
246  if (second_name.empty())
247  second_name = second->get_name();
248  ABG_ASSERT(!second_name.empty());
249 
250  return first_name < second_name;
251  }
252 };
253 
254 /// This is a comparison functor for comparing pointers to @ref
255 /// var_decl.
256 struct var_comp
257 {
258  /// The comparison operator for pointers to @ref var_decl.
259  ///
260  /// It perform a string comparison on the names of the variables.
261  ///
262  /// @param first the first variable to consider for the comparison.
263  ///
264  /// @param second the second variable to consider for the comparison.
265  ///
266  /// @return true if first is less than second, false otherwise.
267  bool
268  operator()(const var_decl* first,
269  const var_decl* second) const
270  {
271  ABG_ASSERT(first != 0 && second != 0);
272 
273  string first_name, second_name;
274  first_name = first->get_linkage_name();
275  if (first_name.empty())
276  {
277  first_name = first->get_pretty_representation();
278  second_name = second->get_pretty_representation();
279  ABG_ASSERT(!second_name.empty());
280  }
281  ABG_ASSERT(!first_name.empty());
282 
283  if (second_name.empty())
284  second_name = second->get_linkage_name();
285 
286  if (second_name.empty())
287  {
288  second_name = second->get_pretty_representation();
289  first_name = first->get_pretty_representation();
290  ABG_ASSERT(!first_name.empty());
291  }
292  ABG_ASSERT(!second_name.empty());
293 
294  return first_name < second_name;
295  }
296 };
297 
298 
299 /// A comparison functor to compare elf_symbols for the purpose of
300 /// sorting.
301 struct comp_elf_symbols_functor
302 {
303  bool
304  operator()(const elf_symbol& l,
305  const elf_symbol& r) const
306  {return l.get_id_string() < r.get_id_string();}
307 
308  bool
309  operator()(const elf_symbol_sptr l,
310  const elf_symbol_sptr r) const
311  {return operator()(*l, *r);}
312 }; // end struct comp_elf_symbols_functor
313 
314 
315 // <corpus stuff>
316 
317 /// Get the maps that associate a name to a certain kind of type.
318 type_maps&
320 {return types_;}
321 
322 /// Get the maps that associate a name to a certain kind of type.
323 const type_maps&
325 {return types_;}
326 
327 /// Return a sorted vector of function symbols for this corpus.
328 ///
329 /// Note that the first time this function is called, the symbols are
330 /// sorted and cached. Subsequent invocations of this function return
331 /// the cached vector that was built previously.
332 ///
333 /// @return the sorted list of function symbols.
334 const elf_symbols&
336 {
337  if (!sorted_fun_symbols)
338  {
339  if (symtab_)
340  {
341  auto filter = symtab_->make_filter();
342  filter.set_functions();
343  sorted_fun_symbols = elf_symbols(symtab_->begin(filter),
344  symtab_->end());
345  }
346  else
347  sorted_fun_symbols = elf_symbols();
348  }
349  return *sorted_fun_symbols;
350 }
351 
352 /// Return a map from name to function symbol for this corpus.
353 ///
354 /// Note that the first time this function is called, the map is built.
355 /// Subsequent invocations of this function return the cached map that was
356 /// built previously.
357 ///
358 /// @return the name function symbol map
361 {
362  if (!fun_symbol_map)
363  {
364  fun_symbol_map = string_elf_symbols_map_type();
365  for (const auto& symbol : get_sorted_fun_symbols())
366  (*fun_symbol_map)[symbol->get_name()].push_back(symbol);
367  }
368  return *fun_symbol_map;
369 }
370 
371 /// Getter for a sorted vector of the function symbols undefined in
372 /// this corpus.
373 ///
374 /// @return a vector of the function symbols undefined in this corpus,
375 /// sorted by name and then version.
376 const elf_symbols&
378 {
379  if (!sorted_undefined_fun_symbols)
380  {
381  if (symtab_)
382  {
383  auto filter = symtab_->make_filter();
384  filter.set_functions();
385  filter.set_undefined_symbols();
386  filter.set_public_symbols(false);
387 
388  sorted_undefined_fun_symbols =
389  elf_symbols(symtab_->begin(filter), symtab_->end());
390  }
391  else
392  sorted_undefined_fun_symbols = elf_symbols();
393  }
394  return *sorted_undefined_fun_symbols;
395 }
396 
397 /// Return a map from name to undefined function symbol for this corpus.
398 ///
399 /// Note that the first time this function is called, the map is built.
400 /// Subsequent invocations of this function return the cached map that was
401 /// built previously.
402 ///
403 /// @return the name function symbol map for undefined symbols
406 {
407  if (!undefined_fun_symbol_map)
408  {
409  undefined_fun_symbol_map = string_elf_symbols_map_type();
410  for (const auto& symbol : get_sorted_undefined_fun_symbols())
411  (*undefined_fun_symbol_map)[symbol->get_name()].push_back(symbol);
412  }
413  return *undefined_fun_symbol_map;
414 }
415 
416 /// Return a list of symbols that are not referenced by any function of
417 /// corpus::get_functions().
418 ///
419 /// Note that this function considers the list of function symbols to keep,
420 /// that is provided by corpus::get_sym_ids_of_fns_to_keep(). If a given
421 /// unreferenced function symbol is not in the list of functions to keep, then
422 /// that symbol is dropped and will not be part of the resulting table of
423 /// unreferenced symbol that is built.
424 ///
425 /// @return list of symbols that are not referenced by any function
426 const elf_symbols&
428 {
429  if (!unrefed_fun_symbols)
430  {
431  unrefed_fun_symbols = elf_symbols();
432  if (symtab_)
433  {
434  unordered_map<string, bool> refed_funs;
435 
436  for (const auto& function : fns)
437  if (elf_symbol_sptr sym = function->get_symbol())
438  {
439  refed_funs[sym->get_id_string()] = true;
440  for (elf_symbol_sptr a = sym->get_next_alias();
441  a && !a->is_main_symbol(); a = a->get_next_alias())
442  refed_funs[a->get_id_string()] = true;
443  }
444 
445  auto filter = symtab_->make_filter();
446  filter.set_functions();
447  for (const auto& symbol :
448  symtab_reader::filtered_symtab(*symtab_, filter))
449  {
450  const std::string sym_id = symbol->get_id_string();
451  if (refed_funs.find(sym_id) == refed_funs.end())
452  {
453  bool keep = sym_id_fns_to_keep.empty();
454  for (const auto& id : sym_id_fns_to_keep)
455  {
456  if (id == sym_id)
457  {
458  keep = true;
459  break;
460  }
461  }
462  if (keep)
463  unrefed_fun_symbols->push_back(symbol);
464  }
465  }
466  }
467  }
468  return *unrefed_fun_symbols;
469 }
470 
471 /// Getter for the sorted vector of variable symbols for this corpus.
472 ///
473 /// Note that the first time this function is called, it computes the
474 /// sorted vector, caches the result and returns it. Subsequent
475 /// invocations of this function just return the cached vector.
476 ///
477 /// @return the sorted vector of variable symbols for this corpus.
478 const elf_symbols&
480 {
481  if (!sorted_var_symbols)
482  {
483  if (symtab_)
484  {
485  auto filter = symtab_->make_filter();
486  filter.set_variables();
487 
488  sorted_var_symbols = elf_symbols(symtab_->begin(filter),
489  symtab_->end());
490  }
491  else
492  sorted_var_symbols = elf_symbols();
493  }
494  return *sorted_var_symbols;
495 }
496 
497 /// Return a map from name to variable symbol for this corpus.
498 ///
499 /// Note that the first time this function is called, the map is built.
500 /// Subsequent invocations of this function return the cached map that was
501 /// built previously.
502 ///
503 /// @return the name variable symbol map
506 {
507  if (!var_symbol_map)
508  {
509  var_symbol_map = string_elf_symbols_map_type();
510  for (const auto& symbol : get_sorted_var_symbols())
511  (*var_symbol_map)[symbol->get_name()].push_back(symbol);
512  }
513  return *var_symbol_map;
514 }
515 
516 /// Getter for a sorted vector of the variable symbols undefined in
517 /// this corpus.
518 ///
519 /// @return a vector of the variable symbols undefined in this corpus,
520 /// sorted by name and then version.
521 const elf_symbols&
523 {
524  if (!sorted_undefined_var_symbols)
525  {
526  if (symtab_)
527  {
528  auto filter = symtab_->make_filter();
529  filter.set_variables();
530  filter.set_undefined_symbols();
531  filter.set_public_symbols(false);
532 
533  sorted_undefined_var_symbols =
534  elf_symbols(symtab_->begin(filter), symtab_->end());
535  }
536  else
537  sorted_undefined_var_symbols = elf_symbols();
538  }
539  return *sorted_undefined_var_symbols;
540 }
541 
542 /// Return a map from name to undefined variable symbol for this corpus.
543 ///
544 /// Note that the first time this function is called, the map is built.
545 /// Subsequent invocations of this function return the cached map that was
546 /// built previously.
547 ///
548 /// @return the name undefined variable symbol map
551 {
552  if (!undefined_var_symbol_map)
553  {
554  undefined_var_symbol_map = string_elf_symbols_map_type();
555  for (const auto& symbol : get_sorted_undefined_var_symbols())
556  (*undefined_var_symbol_map)[symbol->get_name()].push_back(symbol);
557  }
558  return *undefined_var_symbol_map;
559 }
560 
561 /// Return a list of symbols that are not referenced by any variable of
562 /// corpus::get_variables().
563 ///
564 /// Note that this function considers the list of variable symbols to keep,
565 /// that is provided by corpus::get_sym_ids_of_vars_to_keep(). If a given
566 /// unreferenced variable symbol is not in the list of variable to keep, then
567 /// that symbol is dropped and will not be part of the resulting table of
568 /// unreferenced symbol that is built.
569 ///
570 /// @return list of symbols that are not referenced by any variable
571 const elf_symbols&
573 {
574  if (!unrefed_var_symbols)
575  {
576  unrefed_var_symbols = elf_symbols();
577  if (symtab_)
578  {
579  unordered_map<string, bool> refed_vars;
580  for (const auto& variable : vars)
581  if (elf_symbol_sptr sym = variable->get_symbol())
582  {
583  refed_vars[sym->get_id_string()] = true;
584  for (elf_symbol_sptr a = sym->get_next_alias();
585  a && !a->is_main_symbol(); a = a->get_next_alias())
586  refed_vars[a->get_id_string()] = true;
587  }
588 
589  auto filter = symtab_->make_filter();
590  filter.set_variables();
591  for (const auto& symbol :
592  symtab_reader::filtered_symtab(*symtab_, filter))
593  {
594  const std::string sym_id = symbol->get_id_string();
595  if (refed_vars.find(sym_id) == refed_vars.end())
596  {
597  bool keep = sym_id_vars_to_keep.empty();
598  for (const auto& id : sym_id_vars_to_keep)
599  {
600  if (id == sym_id)
601  {
602  keep = true;
603  break;
604  }
605  }
606  if (keep)
607  unrefed_var_symbols->push_back(symbol);
608  }
609  }
610  }
611  }
612  return *unrefed_var_symbols;
613 }
614 
615 
616 /// Getter of the set of pretty representation of types that are
617 /// reachable from public interfaces (global functions and variables).
618 ///
619 /// @return the set of pretty representation of types that are
620 /// reachable from public interfaces (global functions and variables).
621 unordered_set<interned_string, hash_interned_string>*
623 {
624  if (group)
625  return group->get_public_types_pretty_representations();
626 
627  if (pub_type_pretty_reprs_ == 0)
628  pub_type_pretty_reprs_ =
629  new unordered_set<interned_string, hash_interned_string>;
630  return pub_type_pretty_reprs_;
631 }
632 
633 /// Destructor of the @ref corpus::priv type.
635 {
636  delete pub_type_pretty_reprs_;
637 }
638 
639 /// Constructor of the @ref corpus type.
640 ///
641 /// @param env the environment of the corpus.
642 ///
643 /// @param path the path to the file containing the ABI corpus.
644 corpus::corpus(const ir::environment& env, const string& path)
645 {
646  priv_.reset(new priv(path, env));
647  init_format_version();
648 }
649 
650 corpus::~corpus() = default;
651 
652 /// Getter of the enviroment of the corpus.
653 ///
654 /// @return the environment of this corpus.
655 const environment&
657 {return priv_->env;}
658 
659 /// Test if logging was requested.
660 ///
661 /// @return true iff logging was requested.
662 bool
664 {return priv_->do_log;}
665 
666 /// Request logging, or not.
667 ///
668 /// @param f true iff logging is requested.
669 void
671 {priv_->do_log = f;}
672 
673 /// Add a translation unit to the current ABI Corpus.
674 ///
675 /// Note that two translation units with the same path (as returned by
676 /// translation_unit::get_path) cannot be added to the same @ref
677 /// corpus. If that happens, the library aborts.
678 ///
679 /// @param tu the new translation unit to add.
680 void
682 {
683  ABG_ASSERT(priv_->members.insert(tu).second);
684 
685  if (!tu->get_absolute_path().empty())
686  {
687  // Update the path -> translation_unit map.
688  string_tu_map_type::const_iterator i =
689  priv_->path_tu_map.find(tu->get_absolute_path());
690  ABG_ASSERT(i == priv_->path_tu_map.end());
691  priv_->path_tu_map[tu->get_absolute_path()] = tu;
692  }
693 
694  tu->set_corpus(this);
695 }
696 
697 /// Return the list of translation units of the current corpus.
698 ///
699 /// @return the list of translation units of the current corpus.
700 const translation_units&
702 {return priv_->members;}
703 
704 /// Find the translation unit that has a given path.
705 ///
706 /// @param path the path of the translation unit to look for.
707 ///
708 /// @return the translation unit found, if any. Otherwise, return
709 /// nil.
711 corpus::find_translation_unit(const string &path) const
712 {
713  string_tu_map_type::const_iterator i =
714  priv_->path_tu_map.find(path);
715 
716  if (i == priv_->path_tu_map.end())
717  return translation_unit_sptr();
718  return i->second;
719 }
720 
721 /// Erase the translation units contained in this in-memory object.
722 ///
723 /// Note that the on-disk archive file that contains the serialized
724 /// representation of this object is not modified.
725 void
727 {priv_->members.clear();}
728 
729 /// Get the maps that associate a name to a certain kind of type.
730 ///
731 /// @return the maps that associate a name to a certain kind of type.
732 type_maps&
734 {return priv_->types_;}
735 
736 /// Get the maps that associate a name to a certain kind of type.
737 ///
738 /// @return the maps that associate a name to a certain kind of
739 /// type.
740 const type_maps&
742 {return priv_->types_;}
743 
744 /// Get the maps that associate a location string to a certain kind of
745 /// type.
746 ///
747 /// The location string is the result of the invocation to the
748 /// function abigail::ir::location::expand(). It has the form
749 /// "file.c:4:1", with 'file.c' being the file name, '4' being the
750 /// line number and '1' being the column number.
751 ///
752 /// @return the maps.
753 const type_maps&
755 {return priv_->type_per_loc_map_;}
756 
757 /// Test if the recording of reachable types (and thus, indirectly,
758 /// the recording of non-reachable types) is activated for the
759 /// current @ref corpus.
760 ///
761 /// @return true iff the recording of reachable types is activated for
762 /// the current @ref corpus.
763 bool
765 {
766  return (priv_->get_public_types_pretty_representations()
767  && !priv_->get_public_types_pretty_representations()->empty());
768 }
769 
770 /// Record a type as being reachable from public interfaces (global
771 /// functions and variables).
772 ///
773 /// @param t the type to record as reachable.
774 void
776 {
777  string repr = get_pretty_representation(&t, /*internal=*/false);
778  interned_string s = t.get_environment().intern(repr);
779  priv_->get_public_types_pretty_representations()->insert(s);
780 }
781 
782 /// Test if a type is reachable from public interfaces (global
783 /// functions and variables).
784 ///
785 /// For a type to be considered reachable from public interfaces, it
786 /// must have been previously marked as such by calling
787 /// corpus::record_type_as_reachable_from_public_interfaces.
788 ///
789 /// @param t the type to test for.
790 ///
791 /// @return true iff @p t is reachable from public interfaces.
792 bool
794 {
795  string repr = get_pretty_representation(&t, /*internal=*/false);
796  interned_string s = t.get_environment().intern(repr);
797 
798  return (priv_->get_public_types_pretty_representations()->find(s)
799  != priv_->get_public_types_pretty_representations()->end());
800 }
801 
802 /// Getter of a sorted vector of the types that are *NOT* reachable
803 /// from public interfaces.
804 ///
805 /// Note that for this to be non-empty, the libabigail reader that
806 /// analyzed the input (be it a binary or an abixml file) must have be
807 /// configured to load types that are not reachable from public
808 /// interfaces.
809 ///
810 /// @return a reference to a vector of sorted types NON reachable from
811 /// public interfaces.
812 const vector<type_base_wptr>&
814 {
815  if (priv_->types_not_reachable_from_pub_ifaces_.empty())
816  {
817  const type_maps& types = get_types();
818  for (vector<type_base_wptr>::const_iterator it =
819  types.get_types_sorted_by_name().begin();
820  it != types.get_types_sorted_by_name().end();
821  ++it)
822  {
823  type_base_sptr t(*it);
825  priv_->types_not_reachable_from_pub_ifaces_.push_back(t);
826  }
827  }
828 
829  return priv_->types_not_reachable_from_pub_ifaces_;
830 }
831 
832 /// Get the maps that associate a location string to a certain kind of
833 /// type.
834 ///
835 /// The location string is the result of the invocation to the
836 /// function abigail::ir::location::expand(). It has the form
837 /// "file.c:4:1", with 'file.c' being the file name, '4' being the
838 /// line number and '1' being the column number.
839 ///
840 /// @return the maps.
841 type_maps&
843 {return priv_->type_per_loc_map_;}
844 
845 /// Getter of the group this corpus is a member of.
846 ///
847 /// @return the group this corpus is a member of, or nil if it's not
848 /// part of any @ref corpus_group.
849 const corpus_group*
851 {return priv_->group;}
852 
853 /// Getter of the group this corpus belongs to.
854 ///
855 /// @return the group this corpus belong to, or nil if it's not part
856 /// of any @ref corpus_group.
859 {return priv_->group;}
860 
861 /// Setter of the group this corpus belongs to.
862 ///
863 /// @param g the new group.
864 void
865 corpus::set_group(corpus_group* g)
866 {priv_->group = g;}
867 
868 /// Initialize the abixml serialization format version number of the
869 /// corpus.
870 ///
871 /// This function sets the format version number ot the default one
872 /// supported by the current version of Libabigail.
873 void
874 corpus::init_format_version()
875 {
877  (priv_->env.get_config().get_format_major_version_number());
879  (priv_->env.get_config().get_format_minor_version_number());
880 }
881 
882 /// Getter for the origin of the corpus.
883 ///
884 /// @return the origin of the corpus.
887 {return priv_->origin_;}
888 
889 /// Setter for the origin of the corpus.
890 ///
891 /// @param o the new origin for the corpus.
892 void
894 {priv_->origin_ = o;}
895 
896 /// Getter of the major version number of the abixml serialization
897 /// format.
898 ///
899 /// @return the major version number of the abixml format.
900 string&
902 {return priv_->format_major_version_number_;}
903 
904 /// Setter of the major version number of the abixml serialization
905 /// format.
906 ///
907 /// @param maj the new major version numberof the abixml format.
908 void
910 {priv_->format_major_version_number_ = maj;}
911 
912 /// Getter of the minor version number of the abixml serialization
913 /// format.
914 ///
915 /// @return the minor version number of the abixml serialization
916 /// format.
917 string&
919 {return priv_->format_minor_version_number_;}
920 
921 /// Setter of the minor version number of the abixml serialization
922 /// format.
923 ///
924 /// @param min the new minor version number of the abixml
925 /// serialization format.
926 void
928 {priv_->format_minor_version_number_ = min;}
929 
930 /// Get the file path associated to the corpus file.
931 ///
932 /// A subsequent call to corpus::read will deserialize the content of
933 /// the abi file expected at this path; likewise, a call to
934 /// corpus::write will serialize the translation units contained in
935 /// the corpus object into the on-disk file at this path.
936 ///
937 /// @return the file path associated to the current corpus.
938 string&
940 {return priv_->path;}
941 
942 /// Set the file path associated to the corpus file.
943 ///
944 /// A subsequent call to corpus::read will deserialize the content of
945 /// the abi file expected at this path; likewise, a call to
946 /// corpus::write will serialize the translation units contained in
947 /// the corpus object into the on-disk file at this path.
948 ///
949 /// @param path the new file path to assciate to the current corpus.
950 void
951 corpus::set_path(const string& path)
952 {priv_->path = path;}
953 
954 /// Getter of the needed property of the corpus.
955 ///
956 /// This property is meaningful for, e.g, corpora built from ELF
957 /// shared library files. In that case, this is a vector of names of
958 /// dependencies of the ELF shared library file.
959 ///
960 /// @return the vector of dependencies needed by this corpus.
961 const vector<string>&
963 {return priv_->needed;}
964 
965 /// Setter of the needed property of the corpus.
966 ///
967 /// This property is meaningful for, e.g, corpora built from ELF
968 /// shared library files. In that case, this is a vector of names of
969 /// dependencies of the ELF shared library file.
970 ///
971 /// @param needed the new vector of dependencies needed by this
972 /// corpus.
973 void
974 corpus::set_needed(const vector<string>& needed)
975 {priv_->needed = needed;}
976 
977 /// Getter for the soname property of the corpus.
978 ///
979 /// This property is meaningful for, e.g, corpora built from ELF
980 /// shared library files. In that case, this is the shared object
981 /// name exported by the shared library.
982 ///
983 /// @return the soname property of the corpus.
984 const string&
986 {return priv_->soname;}
987 
988 /// Setter for the soname property of the corpus.
989 ///
990 /// This property is meaningful for, e.g, corpora built from ELF
991 /// shared library files. In that case, this is the shared object
992 /// name exported by the shared library.
993 ///
994 /// @param soname the new soname property of the corpus.
995 void
996 corpus::set_soname(const string& soname)
997 {priv_->soname = soname;}
998 
999 /// Getter for the architecture name of the corpus.
1000 ///
1001 /// This property is meaningful for e.g, corpora built from ELF shared
1002 /// library files. In that case, this is a string representation of
1003 /// the Elf{32,64}_Ehdr::e_machine field.
1004 ///
1005 /// @return the architecture name string.
1006 const string&
1008 {return priv_->architecture_name;}
1009 
1010 /// Setter for the architecture name of the corpus.
1011 ///
1012 /// This property is meaningful for e.g, corpora built from ELF shared
1013 /// library files. In that case, this is a string representation of
1014 /// the Elf{32,64}_Ehdr::e_machine field.
1015 ///
1016 /// @param arch the architecture name string.
1017 void
1019 {priv_->architecture_name = arch;}
1020 
1021 /// Tests if the corpus is empty from an ABI surface perspective. I.e. if all
1022 /// of these criteria are true:
1023 /// - all translation units (members) are empty
1024 /// - the maps function and variable symbols are not having entries
1025 /// - for shared libraries:
1026 /// - the soname is empty
1027 /// - there are no DT_NEEDED entries
1028 ///
1029 /// @return true if the corpus contains no translation unit.
1030 bool
1032 {
1033  bool members_empty = true;
1034  for (translation_units::const_iterator i = priv_->members.begin(),
1035  e = priv_->members.end();
1036  i != e; ++i)
1037  {
1038  if (!(*i)->is_empty())
1039  {
1040  members_empty = false;
1041  break;
1042  }
1043  }
1044  return (members_empty
1045  && (!get_symtab() || !get_symtab()->has_symbols())
1046  && priv_->soname.empty()
1047  && priv_->needed.empty()
1048  && priv_->architecture_name.empty()
1049  && !priv_->group);
1050 }
1051 
1052 /// Compare the current @ref corpus against another one.
1053 ///
1054 /// @param other the other corpus to compare against.
1055 ///
1056 /// @return true if the two corpus are equal, false otherwise.
1057 bool
1058 corpus::operator==(const corpus& other) const
1059 {
1060  translation_units::const_iterator i, j;
1061  for (i = get_translation_units().begin(),
1062  j = other.get_translation_units().begin();
1063  (i != get_translation_units().end()
1064  && j != other.get_translation_units().end());
1065  ++i, ++j)
1066  if ((**i) != (**j))
1067  return false;
1068 
1069  return (i == get_translation_units().end()
1070  && j == other.get_translation_units().end());
1071 }
1072 
1073 /// Setter for the symtab object.
1074 ///
1075 /// @param symtab a shared pointer to the new symtab object
1076 void
1078 {priv_->symtab_ = symtab;}
1079 
1080 /// Getter for the symtab object.
1081 ///
1082 /// @return a shared pointer to the symtab object
1085 {return priv_->symtab_;}
1086 
1087 /// Getter for the function symbols map.
1088 ///
1089 /// @return a reference to the function symbols map.
1092 {return priv_->get_fun_symbol_map();}
1093 
1094 /// Getter for the map of function symbols that are undefined in this
1095 /// corpus.
1096 ///
1097 /// @return the map of function symbols not defined in this corpus.
1098 /// The key of the map is the name of the function symbol. The value
1099 /// is a vector of all the function symbols that have the same name.
1102 {return priv_->get_undefined_fun_symbol_map();}
1103 
1104 /// Return a sorted vector of function symbols for this corpus.
1105 ///
1106 /// Note that the first time this function is called, the symbols are
1107 /// sorted and cached. Subsequent invocations of this function return
1108 /// the cached vector that was built previously.
1109 ///
1110 /// @return the sorted list of function symbols.
1111 const elf_symbols&
1113 {return priv_->get_sorted_fun_symbols();}
1114 
1115 /// Getter for a sorted vector of the function symbols undefined in
1116 /// this corpus.
1117 ///
1118 /// @return a vector of the function symbols undefined in this corpus,
1119 /// sorted by name and then version.
1120 const elf_symbols&
1122 {return priv_->get_sorted_undefined_fun_symbols();}
1123 
1124 /// Getter for the sorted vector of variable symbols for this corpus.
1125 ///
1126 /// Note that the first time this function is called, it computes the
1127 /// sorted vector, caches the result and returns it. Subsequent
1128 /// invocations of this function just return the cached vector.
1129 ///
1130 /// @return the sorted vector of variable symbols for this corpus.
1131 const elf_symbols&
1133 {return priv_->get_sorted_var_symbols();}
1134 
1135 /// Getter for a sorted vector of the variable symbols undefined in
1136 /// this corpus.
1137 ///
1138 /// @return a vector of the variable symbols undefined in this corpus,
1139 /// sorted by name and then version.
1140 const elf_symbols&
1142 {return priv_->get_sorted_undefined_var_symbols();}
1143 
1144 /// Getter for the variable symbols map.
1145 ///
1146 /// @return a reference to the variabl symbols map.
1149 {return priv_->get_var_symbol_map();}
1150 
1151 /// Getter for the map of variable symbols that are undefined in this
1152 /// corpus.
1153 ///
1154 /// @return the map of variable symbols not defined in this corpus.
1155 /// The key of the map is the name of the variable symbol. The value
1156 /// is a vector of all the variable symbols that have the same name.
1159 {return priv_->get_undefined_var_symbol_map();}
1160 
1161 /// Look in the function symbols map for a symbol with a given name.
1162 ///
1163 /// @param n the name of the symbol to look for.
1164 ///
1165 /// return the first symbol with the name @p n.
1166 const elf_symbol_sptr
1167 corpus::lookup_function_symbol(const string& n) const
1168 {
1169  if (get_fun_symbol_map().empty())
1170  return elf_symbol_sptr();
1171 
1172  string_elf_symbols_map_type::const_iterator it =
1173  get_fun_symbol_map().find(n);
1174  if ( it == get_fun_symbol_map().end())
1175  return elf_symbol_sptr();
1176  return it->second[0];
1177 }
1178 
1179 /// Look into a set of symbols and look for a symbol that has a given
1180 /// version.
1181 ///
1182 /// This is a sub-routine for corpus::lookup_function_symbol() and
1183 /// corpus::lookup_variable_symbol().
1184 ///
1185 /// @param version the version of the symbol to look for.
1186 ///
1187 /// @param symbols the set of symbols to consider.
1188 ///
1189 /// @return the symbol found, or nil if none was found.
1190 static const elf_symbol_sptr
1191 find_symbol_by_version(const elf_symbol::version& version,
1192  const vector<elf_symbol_sptr>& symbols)
1193 {
1194  if (version.is_empty())
1195  {
1196  // We are looing for a symbol with no version.
1197 
1198  // So first look for possible aliases with no version
1199  for (elf_symbols::const_iterator s = symbols.begin();
1200  s != symbols.end();
1201  ++s)
1202  if ((*s)->get_version().is_empty())
1203  return *s;
1204 
1205  // Or, look for a version that is a default one!
1206  for (elf_symbols::const_iterator s = symbols.begin();
1207  s != symbols.end();
1208  ++s)
1209  if ((*s)->get_version().is_default())
1210  return *s;
1211  }
1212  else
1213  // We are looking for a symbol with a particular defined version.
1214  for (elf_symbols::const_iterator s = symbols.begin();
1215  s != symbols.end();
1216  ++s)
1217  if ((*s)->get_version().str() == version.str())
1218  return *s;
1219 
1220  return elf_symbol_sptr();
1221 }
1222 
1223 /// Look in the function symbols map for a symbol with a given name.
1224 ///
1225 /// @param symbol_name the name of the symbol to look for.
1226 ///
1227 /// @param version the version of the symbol to look for.
1228 ///
1229 /// return the symbol with name @p symbol_name and with version @p
1230 /// version, or nil if no symbol has been found with that name and
1231 /// version.
1232 const elf_symbol_sptr
1233 corpus::lookup_function_symbol(const string& symbol_name,
1234  const elf_symbol::version& version) const
1235 {
1236  if (get_fun_symbol_map().empty())
1237  return elf_symbol_sptr();
1238 
1239  string_elf_symbols_map_type::const_iterator it =
1240  get_fun_symbol_map().find(symbol_name);
1241  if ( it == get_fun_symbol_map().end())
1242  return elf_symbol_sptr();
1243 
1244  return find_symbol_by_version(version, it->second);
1245 }
1246 
1247 /// Look in the function symbols map for a symbol with the same name
1248 /// and version as a given symbol.
1249 ///
1250 /// @param symbol the symbol to look for.
1251 ///
1252 /// return the symbol with the same name and version as @p symbol.
1253 const elf_symbol_sptr
1255 {return lookup_function_symbol(symbol.get_name(), symbol.get_version());}
1256 
1257 /// Look in the variable symbols map for a symbol with a given name.
1258 ///
1259 /// @param n the name of the symbol to look for.
1260 ///
1261 /// return the first symbol with the name @p n.
1262 const elf_symbol_sptr
1263 corpus::lookup_variable_symbol(const string& n) const
1264 {
1265  if (get_var_symbol_map().empty())
1266  return elf_symbol_sptr();
1267 
1268  string_elf_symbols_map_type::const_iterator it =
1269  get_var_symbol_map().find(n);
1270  if ( it == get_var_symbol_map().end())
1271  return elf_symbol_sptr();
1272  return it->second[0];
1273 }
1274 
1275 /// Look in the variable symbols map for a symbol with a given name.
1276 ///
1277 /// @param symbol_name the name of the symbol to look for.
1278 ///
1279 /// @param symbol_version the version of the symbol to look for.
1280 ///
1281 /// return the first symbol with the name @p symbol_name and with
1282 /// version @p version.
1283 const elf_symbol_sptr
1284 corpus::lookup_variable_symbol(const string& symbol_name,
1285  const elf_symbol::version& version) const
1286 {
1287  if (get_var_symbol_map().empty())
1288  return elf_symbol_sptr();
1289 
1290  string_elf_symbols_map_type::const_iterator it =
1291  get_var_symbol_map().find(symbol_name);
1292  if ( it == get_var_symbol_map().end())
1293  return elf_symbol_sptr();
1294 
1295  return find_symbol_by_version(version, it->second);
1296 }
1297 
1298 /// Look in the variable symbols map for a symbol with the same name
1299 /// and version as a given symbol.
1300 ///
1301 /// @param symbol the symbol to look for.
1302 ///
1303 /// return the symbol with the same name and version as @p symbol.
1304 const elf_symbol_sptr
1306 {return lookup_variable_symbol(symbol.get_name(), symbol.get_version());}
1307 
1308 /// Return the functions public decl table of the current corpus.
1309 ///
1310 /// The function public decl tables is a vector of all the functions
1311 /// and member functions found in the current corpus.
1312 ///
1313 /// Note that the caller can suppress some functions from the vector
1314 /// supplying regular expressions describing the set of functions she
1315 /// want to see removed from the public decl table by populating the
1316 /// vector of regular expressions returned by
1317 /// corpus::get_regex_patterns_of_fns_to_suppress().
1318 ///
1319 /// @return the vector of functions of the public decl table. The
1320 /// functions are sorted using their mangled name or name if they
1321 /// don't have mangle names.
1322 const corpus::functions&
1324 {return priv_->fns;}
1325 
1326 /// Lookup the function which has a given function ID.
1327 ///
1328 /// Note that there can have been several functions with the same ID.
1329 /// This is because debug info can declare the same function in
1330 /// several different translation units. Normally, all these function
1331 /// should be equal. But still, this function returns all these
1332 /// functions.
1333 ///
1334 /// @param id the ID of the function to lookup. This ID must be
1335 /// either the result of invoking function::get_id() of
1336 /// elf_symbol::get_id_string().
1337 ///
1338 /// @return the vector functions which ID is @p id, or nil if no
1339 /// function with that ID was found.
1340 const std::unordered_set<function_decl*>*
1341 corpus::lookup_functions(const string& id) const
1342 {
1344  auto i = b->priv_->id_fns_map_.find(id);
1345  if (i == b->priv_->id_fns_map_.end())
1346  return 0;
1347  return &i->second;
1348 }
1349 
1350 /// Sort the set of functions exported by this corpus.
1351 ///
1352 /// Normally, you shouldn't be calling this as the code that creates
1353 /// the corpus for you should do it for you too.
1354 void
1356 {
1357  func_comp fc;
1358  std::sort(priv_->fns.begin(), priv_->fns.end(), fc);
1359 }
1360 
1361 /// Return the public decl table of the global variables of the
1362 /// current corpus.
1363 ///
1364 /// The variable public decls table is a vector of all the public
1365 /// global variables and static member variables found in the current
1366 /// corpus.
1367 ///
1368 /// Note that the caller can suppress some variables from the vector
1369 /// supplying regular expressions describing the set of variables she
1370 /// wants to see removed from the public decl table by populating the
1371 /// vector of regular expressions returned by
1372 /// corpus::get_regex_patterns_of_fns_to_suppress().
1373 ///
1374 /// @return the vector of variables of the public decl table. The
1375 /// variables are sorted using their name.
1376 const corpus::variables&
1378 {return priv_->vars;}
1379 
1380 /// Sort the set of variables exported by this corpus.
1381 ///
1382 /// Normally, you shouldn't be calling this as the code that creates
1383 /// the corpus for you should do it for you too.
1384 void
1386 {
1387  var_comp vc;
1388  std::sort(priv_->vars.begin(), priv_->vars.end(), vc);
1389 }
1390 
1391 /// Getter of the set of function symbols that are not referenced by
1392 /// any function exported by the current corpus.
1393 ///
1394 /// When the corpus has been created from an ELF library or program,
1395 /// this function returns the set of function symbols not referenced
1396 /// by any debug information.
1397 ///
1398 /// @return the vector of function symbols not referenced by any
1399 /// function exported by the current corpus.
1400 const elf_symbols&
1402 {return priv_->get_unreferenced_function_symbols();}
1403 
1404 /// Getter of the set of variable symbols that are not referenced by
1405 /// any variable exported by the current corpus.
1406 ///
1407 /// When the corpus has been created from an ELF library or program,
1408 /// this function returns the set of variable symbols not referenced
1409 /// by any debug information.
1410 ///
1411 /// @return the vector of variable symbols not referenced by any
1412 /// variable exported by the current corpus.
1413 const elf_symbols&
1415 {return priv_->get_unreferenced_variable_symbols();}
1416 
1417 /// Accessor for the regex patterns describing the functions to drop
1418 /// from the public decl table.
1419 ///
1420 /// @return the regex patterns describing the functions to drop from
1421 /// the public decl table.
1422 vector<string>&
1424 {return priv_->regex_patterns_fns_to_suppress;}
1425 
1426 /// Accessor for the regex patterns describing the functions to drop
1427 /// from the public decl table.
1428 ///
1429 /// @return the regex patterns describing the functions to drop from
1430 /// the public decl table.
1431 const vector<string>&
1433 {return priv_->regex_patterns_fns_to_suppress;}
1434 
1435 /// Accessor for the regex patterns describing the variables to drop
1436 /// from the public decl table.
1437 ///
1438 /// @return the regex patterns describing the variables to drop from
1439 /// the public decl table.
1440 vector<string>&
1442 {return priv_->regex_patterns_vars_to_suppress;}
1443 
1444 /// Accessor for the regex patterns describing the variables to drop
1445 /// from the public decl table.
1446 ///
1447 /// @return the regex patterns describing the variables to drop from
1448 /// the public decl table.
1449 const vector<string>&
1451 {return priv_->regex_patterns_vars_to_suppress;}
1452 
1453 /// Accessor for the regex patterns describing the functions to keep
1454 /// into the public decl table. The other functions not matches by these
1455 /// regexes are dropped from the public decl table.
1456 ///
1457 /// @return the regex patterns describing the functions to keep into
1458 /// the public decl table.
1459 vector<string>&
1461 {return priv_->regex_patterns_fns_to_keep;}
1462 
1463 /// Accessor for the regex patterns describing the functions to keep
1464 /// into the public decl table. The other functions not matches by these
1465 /// regexes are dropped from the public decl table.
1466 ///
1467 /// @return the regex patterns describing the functions to keep into
1468 /// the public decl table.
1469 const vector<string>&
1471 {return priv_->regex_patterns_fns_to_keep;}
1472 
1473 /// Getter for the vector of function symbol IDs to keep.
1474 ///
1475 /// A symbol ID is a string made of the name of the symbol and its
1476 /// version, separated by one or two '@'.
1477 ///
1478 /// @return a vector of IDs of function symbols to keep.
1479 vector<string>&
1481 {return priv_->sym_id_fns_to_keep;}
1482 
1483 /// Getter for the vector of function symbol IDs to keep.
1484 ///
1485 /// A symbol ID is a string made of the name of the symbol and its
1486 /// version, separated by one or two '@'.
1487 ///
1488 /// @return a vector of IDs of function symbols to keep.
1489 const vector<string>&
1491 {return priv_->sym_id_fns_to_keep;}
1492 
1493 /// Accessor for the regex patterns describing the variables to keep
1494 /// into the public decl table. The other variables not matches by these
1495 /// regexes are dropped from the public decl table.
1496 ///
1497 /// @return the regex patterns describing the variables to keep into
1498 /// the public decl table.
1499 vector<string>&
1501 {return priv_->regex_patterns_vars_to_keep;}
1502 
1503 /// Accessor for the regex patterns describing the variables to keep
1504 /// into the public decl table. The other variables not matches by these
1505 /// regexes are dropped from the public decl table.
1506 ///
1507 /// @return the regex patterns describing the variables to keep into
1508 /// the public decl table.
1509 const vector<string>&
1511 {return priv_->regex_patterns_vars_to_keep;}
1512 
1513 /// Getter for the vector of variable symbol IDs to keep.
1514 ///
1515 /// A symbol ID is a string made of the name of the symbol and its
1516 /// version, separated by one or two '@'.
1517 ///
1518 /// @return a vector of IDs of variable symbols to keep.
1519 vector<string>&
1521 {return priv_->sym_id_vars_to_keep;}
1522 
1523 /// Getter for the vector of variable symbol IDs to keep.
1524 ///
1525 /// A symbol ID is a string made of the name of the symbol and its
1526 /// version, separated by one or two '@'.
1527 ///
1528 /// @return a vector of IDs of variable symbols to keep.
1529 const vector<string>&
1531 {return priv_->sym_id_vars_to_keep;}
1532 
1533 /// After the set of exported functions and variables have been built,
1534 /// consider all the tunables that control that set and see if some
1535 /// functions need to be removed from that set; if so, remove them.
1536 void
1538 {
1539  string sym_name, sym_version;
1540 
1541  vector<function_decl*> fns_to_keep;
1543  for (vector<function_decl*>::iterator f = priv_->fns.begin();
1544  f != priv_->fns.end();
1545  ++f)
1546  {
1547  if (b->priv_->keep_wrt_id_of_fns_to_keep(*f)
1548  && b->priv_->keep_wrt_regex_of_fns_to_suppress(*f)
1549  && b->priv_->keep_wrt_regex_of_fns_to_keep(*f))
1550  fns_to_keep.push_back(*f);
1551  }
1552  priv_->fns = fns_to_keep;
1553 
1554  vector<var_decl*> vars_to_keep;
1555  for (vector<var_decl*>::iterator v = priv_->vars.begin();
1556  v != priv_->vars.end();
1557  ++v)
1558  {
1559  if (b->priv_->keep_wrt_id_of_vars_to_keep(*v)
1560  && b->priv_->keep_wrt_regex_of_vars_to_suppress(*v)
1561  && b->priv_->keep_wrt_regex_of_vars_to_keep(*v))
1562  vars_to_keep.push_back(*v);
1563  }
1564  priv_->vars = vars_to_keep;
1565 }
1566 
1567 /// Getter for the object that is responsible for determining what
1568 /// decls ought to be in the set of exported decls.
1569 ///
1570 /// The object does have methods to add the decls to the set of
1571 /// exported decls, right at the place where the corpus expects it,
1572 /// so that there is no unnecessary copying involved.
1573 ///
1574 /// @return a (smart) pointer to the instance of @ref
1575 /// corpus::exported_decls_builder that is responsible for determine
1576 /// what decls ought to be in the set of exported decls.
1579 {
1580  if (!priv_->exported_decls_builder)
1581  {
1582  priv_->exported_decls_builder.reset
1583  (new exported_decls_builder(priv_->fns,
1584  priv_->vars,
1585  priv_->regex_patterns_fns_to_suppress,
1586  priv_->regex_patterns_vars_to_suppress,
1587  priv_->regex_patterns_fns_to_keep,
1588  priv_->regex_patterns_vars_to_keep,
1589  priv_->sym_id_fns_to_keep,
1590  priv_->sym_id_vars_to_keep));
1591  }
1592  return priv_->exported_decls_builder;
1593 }
1594 
1595 /// Bitwise | operator for the corpus::origin type.
1596 ///
1597 /// @param l the left-hand side operand of the | operation.
1598 ///
1599 /// @param r the right-hand side operand of the | operation.
1600 ///
1601 /// @return the result of the operation.
1604 {
1605  return static_cast<corpus::origin>
1606  (static_cast<uint32_t>(l) | static_cast<uint32_t>(r));
1607 }
1608 
1609 /// Bitwise |= operator for the corpus::origin type.
1610 ///
1611 /// @param l the left-hand side operand for the |= operation.
1612 ///
1613 /// @param r the right-hand side operand for the |= operation.
1614 ///
1615 /// @return the result of the operation.
1618 {
1619  l = l | r;
1620  return l;
1621 }
1622 
1623 /// Bitwise & operator for the corpus::origin type.
1624 ///
1625 /// @param l the left-hand side operand of the & operation.
1626 ///
1627 /// @param r the right-hand side operand of the & operation.
1628 ///
1629 /// @return the result of the operation.
1632 {
1633  return static_cast<corpus::origin>
1634  (static_cast<uint32_t>(l) & static_cast<uint32_t>(r));
1635 }
1636 
1637 /// Bitwise &= operator for the corpus::origin type.
1638 ///
1639 /// @param l the left-hand side operand of the &= operation.
1640 ///
1641 /// @param r the right-hand side operand of the &= operation.
1642 ///
1643 /// @return the result of the operation.
1646 {
1647  l = l & r;
1648  return l;
1649 }
1650 
1651 // </corpus stuff>
1652 
1653 // <corpus_group stuff>
1654 
1655 /// Type of the private data of @ref corpus_group
1656 struct corpus_group::priv
1657 {
1658  std::set<string> corpora_paths;
1659  corpora_type corpora;
1660  istring_function_decl_ptr_map_type fns_map;
1661  vector<function_decl*> fns;
1662  istring_var_decl_ptr_map_type vars_map;
1663  vector<var_decl*> vars;
1664  string_elf_symbols_map_type var_symbol_map;
1665  string_elf_symbols_map_type fun_symbol_map;
1666  elf_symbols sorted_var_symbols;
1667  elf_symbols sorted_fun_symbols;
1668  unordered_map<string, elf_symbol_sptr> unrefed_fun_symbol_map;
1669  elf_symbols unrefed_fun_symbols;
1670  bool unrefed_fun_symbols_built;
1671  unordered_map<string, elf_symbol_sptr> unrefed_var_symbol_map;
1672  elf_symbols unrefed_var_symbols;
1673  bool unrefed_var_symbols_built;
1674  unordered_set<interned_string, hash_interned_string> pub_type_pretty_reprs_;
1675 
1676  priv()
1677  : unrefed_fun_symbols_built(),
1678  unrefed_var_symbols_built()
1679  {}
1680 
1681  /// Add symbols to the set of corpus group function symbols that are
1682  /// *NOT* referenced by debug info.
1683  ///
1684  /// @param syms the set the symbols to add.
1685  void
1686  add_unref_fun_symbols(const elf_symbols& syms)
1687  {
1688  for (elf_symbols::const_iterator e =
1689  syms.begin(); e != syms.end(); ++e)
1690  {
1691  string sym_id = (*e)->get_id_string();
1692  unordered_map<string, elf_symbol_sptr>::const_iterator j =
1693  unrefed_fun_symbol_map.find(sym_id);
1694  if (j != unrefed_fun_symbol_map.end())
1695  continue;
1696 
1697  unrefed_fun_symbol_map[sym_id] = *e;
1698  unrefed_fun_symbols.push_back(*e);
1699  }
1700  unrefed_fun_symbols_built = true;
1701  }
1702 
1703  /// Add symbols to the set of corpus group variable symbols that are
1704  /// *NOT* referenced by debug info.
1705  ///
1706  /// @param syms the set the symbols to add.
1707  void
1708  add_unref_var_symbols(const elf_symbols& syms)
1709  {
1710  for (elf_symbols::const_iterator e =
1711  syms.begin(); e != syms.end(); ++e)
1712  {
1713  string sym_id = (*e)->get_id_string();
1714  unordered_map<string, elf_symbol_sptr>::const_iterator j =
1715  unrefed_var_symbol_map.find(sym_id);
1716  if (j != unrefed_var_symbol_map.end())
1717  continue;
1718 
1719  unrefed_var_symbol_map[sym_id] = *e;
1720  unrefed_var_symbols.push_back(*e);
1721  }
1722  unrefed_var_symbols_built = true;
1723  }
1724 }; // end corpus_group::priv
1725 
1726 /// Constructor of the @ref corpus_group type.
1727 ///
1728 /// @param env the environment of the @ref corpus_group.
1729 ///
1730 /// @param path the path to the file represented by the corpus group.
1731 corpus_group::corpus_group(const environment& env, const string& path = "")
1732  : corpus(env, path), priv_(new priv)
1733 {}
1734 
1735 /// Desctructor of the @ref corpus_group type.
1737 {}
1738 
1739 /// Add a new corpus to the current instance of @ref corpus_group.
1740 ///
1741 /// @param corp the new corpus to add.
1742 void
1743 corpus_group::add_corpus(const corpus_sptr& corp)
1744 {
1745  if (!corp)
1746  return;
1747 
1748  if (!corp->get_path().empty()
1749  && has_corpus(corp->get_path()))
1750  return;
1751 
1752  // Ensure the new architecture name matches the current one.
1753  string cur_arch = get_architecture_name(),
1754  corp_arch = corp->get_architecture_name();
1755  if (cur_arch.empty())
1756  set_architecture_name(corp_arch);
1757  else if (cur_arch != corp_arch)
1758  {
1759  std::cerr << "corpus '" << corp->get_path() << "'"
1760  << " has architecture '" << corp_arch << "'"
1761  << " but expected '" << cur_arch << "'\n";
1763  }
1764 
1765  priv_->corpora.push_back(corp);
1766  corp->set_group(this);
1767  priv_->corpora_paths.insert(corp->get_path());
1768 
1769  /// Add the unreferenced function and variable symbols of this
1770  /// corpus to the unreferenced symbols of the current corpus group.
1771  priv_->add_unref_fun_symbols(get_unreferenced_function_symbols());
1772  priv_->add_unref_var_symbols(get_unreferenced_variable_symbols());
1773 }
1774 
1775 /// Test if a corpus of a given path has been added to the group.
1776 ///
1777 /// @param path the path to the corpus to consider.
1778 ///
1779 /// @return true iff a corpus with path @p path is already present in
1780 /// the groupâ‹…
1781 bool
1782 corpus_group::has_corpus(const string& path)
1783 {
1784  if (priv_->corpora_paths.find(path) != priv_->corpora_paths.end())
1785  return true;
1786  return false;
1787 }
1788 
1789 /// Getter of the vector of corpora held by the current @ref
1790 /// corpus_group.
1791 ///
1792 /// @return the vector corpora.
1793 const corpus_group::corpora_type&
1795 {return priv_->corpora;}
1796 
1797 /// Getter of the first corpus added to this Group.
1798 ///
1799 /// @return the first corpus added to this Group.
1800 const corpus_sptr
1802 {return const_cast<corpus_group*>(this)->get_main_corpus();}
1803 
1804 /// Getter of the first corpus added to this Group.
1805 ///
1806 /// @return the first corpus added to this Group.
1807 corpus_sptr
1809 {
1810  if (!get_corpora().empty())
1811  return get_corpora().front();
1812  return corpus_sptr();
1813 }
1814 
1815 /// Test if the current corpus group is empty.
1816 ///
1817 /// @return true iff the current corpus group is empty.
1818 bool
1820 {return get_corpora().empty();}
1821 
1822 /// Get the functions exported by the corpora of the current corpus
1823 /// group.
1824 ///
1825 /// Upon its first invocation, this function walks the corpora
1826 /// contained in the corpus group and caches the functions they exported.
1827 ///
1828 /// Subsequent invocations just return the cached functions.
1829 ///
1830 /// @return the exported functions.
1831 const corpus::functions&
1833 {
1834  if (priv_->fns.empty())
1835  for (corpora_type::const_iterator i = get_corpora().begin();
1836  i != get_corpora().end();
1837  ++i)
1838  {
1839  corpus_sptr c = *i;
1840  for (corpus::functions::const_iterator f = c->get_functions().begin();
1841  f != c->get_functions().end();
1842  ++f)
1843  {
1844  interned_string fid = (*f)->get_id();
1845  istring_function_decl_ptr_map_type::const_iterator j =
1846  priv_->fns_map.find(fid);
1847 
1848  if (j != priv_->fns_map.end())
1849  // Don't cache the same function twice ...
1850  continue;
1851 
1852  priv_->fns_map[fid] = *f;
1853  // really cache the function now.
1854  priv_->fns.push_back(*f);
1855  }
1856  }
1857 
1858  return priv_->fns;
1859 }
1860 
1861 /// Get the global variables exported by the corpora of the current
1862 /// corpus group.
1863 ///
1864 /// Upon its first invocation, this function walks the corpora
1865 /// contained in the corpus group and caches the variables they
1866 /// export.
1867 ///
1868 /// @return the exported variables.
1869 const corpus::variables&
1871 {
1872  if (priv_->vars.empty())
1873  for (corpora_type::const_iterator i = get_corpora().begin();
1874  i != get_corpora().end();
1875  ++i)
1876  {
1877  corpus_sptr c = *i;
1878  for (corpus::variables::const_iterator v = c->get_variables().begin();
1879  v != c->get_variables().end();
1880  ++v)
1881  {
1882  interned_string vid = (*v)->get_id();
1883  istring_var_decl_ptr_map_type::const_iterator j =
1884  priv_->vars_map.find(vid);
1885 
1886  if (j != priv_->vars_map.end())
1887  // Don't cache the same variable twice ...
1888  continue;
1889 
1890  priv_->vars_map[vid] = *v;
1891  // Really cache the variable now.
1892  priv_->vars.push_back(*v);
1893  }
1894  }
1895 
1896  return priv_->vars;
1897 }
1898 
1899 /// Get the symbols of the global variables exported by the corpora of
1900 /// the current @ref corpus_group.
1901 ///
1902 /// @return the symbols of the global variables exported by the corpora
1905 {
1906  if (priv_->var_symbol_map.empty())
1907  for (corpora_type::const_iterator i = get_corpora().begin();
1908  i != get_corpora().end();
1909  ++i)
1910  priv_->var_symbol_map.insert((*i)->get_var_symbol_map().begin(),
1911  (*i)->get_var_symbol_map().end());
1912 
1913  return priv_->var_symbol_map;
1914 }
1915 
1916 /// Get the symbols of the global functions exported by the corpora of
1917 /// the current @ref corpus_group.
1918 ///
1919 /// @return the symbols of the global functions exported by the corpora
1922 {
1923  if (priv_->fun_symbol_map.empty())
1924  for (corpora_type::const_iterator i = get_corpora().begin();
1925  i != get_corpora().end();
1926  ++i)
1927  priv_->fun_symbol_map.insert((*i)->get_fun_symbol_map().begin(),
1928  (*i)->get_fun_symbol_map().end());
1929 
1930  return priv_->fun_symbol_map;
1931 }
1932 
1933 /// Get a sorted vector of the symbols of the functions exported by
1934 /// the corpora of the current group.
1935 ///
1936 /// @return the sorted vectors of the exported function symbols.
1937 const elf_symbols&
1939 {
1940  if (priv_->sorted_fun_symbols.empty()
1941  && !get_fun_symbol_map().empty())
1942  {
1943  for (corpora_type::const_iterator i = get_corpora().begin();
1944  i != get_corpora().end();
1945  ++i)
1946  {
1947  corpus_sptr c = *i;
1948  for (string_elf_symbols_map_type::const_iterator j =
1949  c->get_fun_symbol_map().begin();
1950  j != c->get_fun_symbol_map().begin();
1951  ++j)
1952  priv_->sorted_fun_symbols.insert(priv_->sorted_fun_symbols.end(),
1953  j->second.begin(),
1954  j->second.end());
1955  }
1956  comp_elf_symbols_functor comp;
1957  std::sort(priv_->sorted_fun_symbols.begin(),
1958  priv_->sorted_fun_symbols.end(),
1959  comp);
1960  }
1961 
1962  return priv_->sorted_fun_symbols;
1963 }
1964 
1965 /// Get a sorted vector of the symbols of the variables exported by
1966 /// the corpora of the current group.
1967 ///
1968 /// @return the sorted vectors of the exported variable symbols.
1969 const elf_symbols&
1971 {
1972  if (priv_->sorted_var_symbols.empty()
1973  && !get_var_symbol_map().empty())
1974  {
1975  for (corpora_type::const_iterator i = get_corpora().begin();
1976  i != get_corpora().end();
1977  ++i)
1978  {
1979  corpus_sptr c = *i;
1980  for (string_elf_symbols_map_type::const_iterator j =
1981  c->get_var_symbol_map().begin();
1982  j != c->get_var_symbol_map().begin();
1983  ++j)
1984  priv_->sorted_var_symbols.insert(priv_->sorted_var_symbols.end(),
1985  j->second.begin(),
1986  j->second.end());
1987  }
1988  comp_elf_symbols_functor comp;
1989  std::sort(priv_->sorted_var_symbols.begin(),
1990  priv_->sorted_var_symbols.end(),
1991  comp);
1992  }
1993 
1994  return priv_->sorted_var_symbols;
1995 }
1996 
1997 /// Get the set of function symbols not referenced by any debug info,
1998 /// from all the corpora of the current corpus group.
1999 ///
2000 /// Upon its first invocation, this function possibly walks all the
2001 /// copora of this corpus group and caches the unreferenced symbols
2002 /// they export. The function then returns the cache.
2003 ///
2004 /// Upon subsequent invocations, this functions just returns the
2005 /// cached symbols.
2006 ///
2007 /// @return the unreferenced symbols.
2008 const elf_symbols&
2010 {
2011  if (!priv_->unrefed_fun_symbols_built)
2012  if (priv_->unrefed_fun_symbols.empty())
2013  {
2014  for (corpora_type::const_iterator i = get_corpora().begin();
2015  i != get_corpora().end();
2016  ++i)
2017  {
2018  corpus_sptr c = *i;
2019  for (elf_symbols::const_iterator e =
2020  c->get_unreferenced_function_symbols().begin();
2021  e != c->get_unreferenced_function_symbols().end();
2022  ++e)
2023  {
2024  string sym_id = (*e)->get_id_string();
2025  unordered_map<string, elf_symbol_sptr>::const_iterator j =
2026  priv_->unrefed_fun_symbol_map.find(sym_id);
2027  if (j != priv_->unrefed_fun_symbol_map.end())
2028  continue;
2029 
2030  priv_->unrefed_fun_symbol_map[sym_id] = *e;
2031  priv_->unrefed_fun_symbols.push_back(*e);
2032  }
2033  }
2034  priv_->unrefed_fun_symbols_built = true;
2035  }
2036 
2037  return priv_->unrefed_fun_symbols;
2038 }
2039 
2040 /// Get the set of variable symbols not referenced by any debug info,
2041 /// from all the corpora of the current corpus group.
2042 ///
2043 /// Upon its first invocation, this function possibly walks all the
2044 /// copora of this corpus group and caches the unreferenced symbols
2045 /// they export. The function then returns the cache.
2046 ///
2047 /// Upon subsequent invocations, this functions just returns the
2048 /// cached symbols.
2049 ///
2050 /// @return the unreferenced symbols.
2051 const elf_symbols&
2053 {
2054  if (!priv_->unrefed_var_symbols_built)
2055  if (priv_->unrefed_var_symbols.empty())
2056  {
2057  for (corpora_type::const_iterator i = get_corpora().begin();
2058  i != get_corpora().end();
2059  ++i)
2060  {
2061  corpus_sptr c = *i;
2062  for (elf_symbols::const_iterator e =
2063  c->get_unreferenced_variable_symbols().begin();
2064  e != c->get_unreferenced_variable_symbols().end();
2065  ++e)
2066  {
2067  string sym_id = (*e)->get_id_string();
2068  unordered_map<string, elf_symbol_sptr>::const_iterator j =
2069  priv_->unrefed_var_symbol_map.find(sym_id);
2070  if (j != priv_->unrefed_var_symbol_map.end())
2071  continue;
2072 
2073  priv_->unrefed_var_symbol_map[sym_id] = *e;
2074  priv_->unrefed_var_symbols.push_back(*e);
2075  }
2076  }
2077  priv_->unrefed_var_symbols_built = true;
2078  }
2079 
2080  return priv_->unrefed_var_symbols;
2081 }
2082 
2083 /// Getter of a pointer to the set of types reachable from public
2084 /// interfaces of a given corpus group.
2085 unordered_set<interned_string, hash_interned_string>*
2087 {return &priv_->pub_type_pretty_reprs_;}
2088 
2089 /// Test if the recording of reachable types (and thus, indirectly,
2090 /// the recording of non-reachable types) is activated for the
2091 /// current @ref corpus_group.
2092 ///
2093 /// @return true iff the recording of reachable types is activated for
2094 /// the current @ref corpus_group.
2095 bool
2097 {return !get_public_types_pretty_representations()->empty();}
2098 
2099 // </corpus_group stuff>
2100 
2101 }// end namespace ir
2102 }// end namespace abigail
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.
Definition: abg-fwd.h:1610
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition: abg-fwd.h:1659
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.
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
The abstraction of an interned string.
The type of the private data of corpus::exported_decls_builder type.
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:304
const functions & exported_functions() const
Getter for the reference to the vector of exported functions. This vector is shared with with the cor...
Definition: abg-corpus.cc:101
void maybe_add_fn_to_exported_fns(function_decl *)
Consider at all the tunables that control wether a function should be added to the set of exported fu...
Definition: abg-corpus.cc:159
std::unordered_set< function_decl * > * fn_id_maps_to_several_fns(function_decl *)
Test if a given function ID maps to several functions in the same corpus.
Definition: abg-corpus.cc:125
void maybe_add_var_to_exported_vars(const var_decl *)
Consider at all the tunables that control wether a variable should be added to the set of exported va...
Definition: abg-corpus.cc:182
const variables & exported_variables() const
Getter for the reference to the vector of exported variables. This vector is shared with with the cor...
Definition: abg-corpus.cc:141
Abstraction of a group of corpora.
Definition: abg-corpus.h:353
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.
Definition: abg-corpus.cc:1970
bool has_corpus(const string &)
Test if a corpus of a given path has been added to the group.
Definition: abg-corpus.cc:1782
const corpora_type & get_corpora() const
Getter of the vector of corpora held by the current corpus_group.
Definition: abg-corpus.cc:1794
unordered_set< interned_string, hash_interned_string > * get_public_types_pretty_representations()
Getter of a pointer to the set of types reachable from public interfaces of a given corpus group.
Definition: abg-corpus.cc:2086
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.
Definition: abg-corpus.cc:1904
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.
Definition: abg-corpus.cc:1938
virtual bool is_empty() const
Test if the current corpus group is empty.
Definition: abg-corpus.cc:1819
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.
Definition: abg-corpus.cc:1921
const corpus_sptr get_main_corpus() const
Getter of the first corpus added to this Group.
Definition: abg-corpus.cc:1801
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...
Definition: abg-corpus.cc:2009
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...
Definition: abg-corpus.cc:2052
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)...
Definition: abg-corpus.cc:2096
virtual const corpus::variables & get_variables() const
Get the global variables exported by the corpora of the current corpus group.
Definition: abg-corpus.cc:1870
virtual ~corpus_group()
Desctructor of the corpus_group type.
Definition: abg-corpus.cc:1736
void add_corpus(const corpus_sptr &)
Add a new corpus to the current instance of corpus_group.
Definition: abg-corpus.cc:1743
virtual const corpus::functions & get_functions() const
Get the functions exported by the corpora of the current corpus group.
Definition: abg-corpus.cc:1832
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
Definition: abg-corpus.cc:1132
const elf_symbol_sptr lookup_function_symbol(const string &n) const
Look in the function symbols map for a symbol with a given name.
Definition: abg-corpus.cc:1167
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:45
void sort_functions()
Sort the set of functions exported by this corpus.
Definition: abg-corpus.cc:1355
void set_soname(const string &)
Setter for the soname property of the corpus.
Definition: abg-corpus.cc:996
const std::unordered_set< function_decl * > * lookup_functions(const string &id) const
Lookup the function which has a given function ID.
Definition: abg-corpus.cc:1341
const vector< type_base_wptr > & get_types_not_reachable_from_public_interfaces() const
Getter of a sorted vector of the types that are *NOT* reachable from public interfaces.
Definition: abg-corpus.cc:813
void record_type_as_reachable_from_public_interfaces(const type_base &)
Record a type as being reachable from public interfaces (global functions and variables).
Definition: abg-corpus.cc:775
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
Definition: abg-corpus.cc:962
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...
Definition: abg-corpus.cc:1578
void maybe_drop_some_exported_decls()
After the set of exported functions and variables have been built, consider all the tunables that con...
Definition: abg-corpus.cc:1537
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.
Definition: abg-corpus.cc:1158
void add(const translation_unit_sptr &)
Add a translation unit to the current ABI Corpus.
Definition: abg-corpus.cc:681
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
Definition: abg-corpus.cc:1148
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition: abg-corpus.h:36
const elf_symbol_sptr lookup_variable_symbol(const string &n) const
Look in the variable symbols map for a symbol with a given name.
Definition: abg-corpus.cc:1263
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
Definition: abg-corpus.cc:1112
const string & get_soname()
Getter for the soname property of the corpus.
Definition: abg-corpus.cc:985
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:701
const symtab_reader::symtab_sptr & get_symtab() const
Getter for the symtab object.
Definition: abg-corpus.cc:1084
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:886
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:
Definition: abg-corpus.cc:1031
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:733
vector< string > & get_sym_ids_of_vars_to_keep()
Getter for the vector of variable symbol IDs to keep.
Definition: abg-corpus.cc:1520
bool do_log() const
Test if logging was requested.
Definition: abg-corpus.cc:663
const translation_unit_sptr find_translation_unit(const string &path) const
Find the translation unit that has a given path.
Definition: abg-corpus.cc:711
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
Definition: abg-corpus.cc:1121
vector< var_decl * > variables
Convenience typedef for std::vector<abigail::ir::var_decl*>
Definition: abg-corpus.h:34
string & get_path() const
Get the file path associated to the corpus file.
Definition: abg-corpus.cc:939
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.
Definition: abg-corpus.cc:1101
void set_origin(origin)
Setter for the origin of the corpus.
Definition: abg-corpus.cc:893
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
Definition: abg-corpus.cc:1091
bool operator==(const corpus &) const
Compare the current corpus against another one.
Definition: abg-corpus.cc:1058
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
Definition: abg-corpus.cc:842
void drop_translation_units()
Erase the translation units contained in this in-memory object.
Definition: abg-corpus.cc:726
void sort_variables()
Sort the set of variables exported by this corpus.
Definition: abg-corpus.cc:1385
vector< string > & get_regex_patterns_of_vars_to_keep()
Accessor for the regex patterns describing the variables to keep into the public decl table....
Definition: abg-corpus.cc:1500
vector< string > & get_regex_patterns_of_vars_to_suppress()
Accessor for the regex patterns describing the variables to drop from the public decl table.
Definition: abg-corpus.cc:1441
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:850
vector< string > & get_regex_patterns_of_fns_to_suppress()
Accessor for the regex patterns describing the functions to drop from the public decl table.
Definition: abg-corpus.cc:1423
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...
Definition: abg-corpus.cc:1401
void set_path(const string &)
Set the file path associated to the corpus file.
Definition: abg-corpus.cc:951
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...
Definition: abg-corpus.cc:1414
bool type_is_reachable_from_public_interfaces(const type_base &) const
Test if a type is reachable from public interfaces (global functions and variables).
Definition: abg-corpus.cc:793
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)...
Definition: abg-corpus.cc:764
virtual const variables & get_variables() const
Return the public decl table of the global variables of the current corpus.
Definition: abg-corpus.cc:1377
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
Definition: abg-corpus.cc:1141
void set_needed(const vector< string > &)
Setter of the needed property of the corpus.
Definition: abg-corpus.cc:974
vector< string > & get_sym_ids_of_fns_to_keep()
Getter for the vector of function symbol IDs to keep.
Definition: abg-corpus.cc:1480
vector< function_decl * > functions
Convenience typedef for std::vector<abigail::ir::function_decl*>
Definition: abg-corpus.h:31
void set_architecture_name(const string &)
Setter for the architecture name of the corpus.
Definition: abg-corpus.cc:1018
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
Definition: abg-corpus.cc:1077
void set_format_major_version_number(const string &)
Setter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:909
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
Definition: abg-corpus.cc:1007
vector< string > strings_type
A convenience typedef for std::vector<string>.
Definition: abg-corpus.h:28
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:656
vector< string > & get_regex_patterns_of_fns_to_keep()
Accessor for the regex patterns describing the functions to keep into the public decl table....
Definition: abg-corpus.cc:1460
void set_format_minor_version_number(const string &)
Setter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:927
string & get_format_minor_version_number() const
Getter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:918
virtual const functions & get_functions() const
Return the functions public decl table of the current corpus.
Definition: abg-corpus.cc:1323
string & get_format_major_version_number() const
Getter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:901
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4960
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4909
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition: abg-ir.cc:4726
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1180
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3026
Abstraction of an elf symbol.
Definition: abg-ir.h:909
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:1986
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2045
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:140
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3792
Abstraction for a function declaration.
Definition: abg-ir.h:3047
An abstraction helper for type declarations.
Definition: abg-ir.h:1960
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition: abg-ir.h:585
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition: abg-ir.cc:1129
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4331
Abstracts a variable declaration.
Definition: abg-ir.h:2944
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return the pretty representation of this variable.
Definition: abg-ir.cc:20323
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1617
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:872
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition: abg-ir.cc:9260
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
Definition: abg-ir.h:890
unordered_map< string, const function_decl * > str_fn_ptr_map_type
Convenience typedef for a hash map of string and pointer to function_decl.
Definition: abg-corpus.cc:210
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1603
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.
Definition: abg-corpus.cc:206
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1631
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:134
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.
Definition: abg-corpus.cc:216
std::set< translation_unit_sptr, shared_translation_unit_comp > translation_units
Convenience typedef for an ordered set of translation_unit_sptr.
Definition: abg-ir.h:837
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1645
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.
Definition: abg-ir.h:895
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition: abg-fwd.h:88
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.
Definition: abg-corpus.cc:479
const string_elf_symbols_map_type & get_undefined_var_symbol_map() const
Return a map from name to undefined variable symbol for this corpus.
Definition: abg-corpus.cc:550
unordered_set< interned_string, hash_interned_string > * get_public_types_pretty_representations()
Getter of the set of pretty representation of types that are reachable from public interfaces (global...
Definition: abg-corpus.cc:622
const string_elf_symbols_map_type & get_var_symbol_map() const
Return a map from name to variable symbol for this corpus.
Definition: abg-corpus.cc:505
const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
Definition: abg-corpus.cc:335
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:319
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
Definition: abg-corpus.cc:377
const string_elf_symbols_map_type & get_undefined_fun_symbol_map() const
Return a map from name to undefined function symbol for this corpus.
Definition: abg-corpus.cc:405
const string_elf_symbols_map_type & get_fun_symbol_map() const
Return a map from name to function symbol for this corpus.
Definition: abg-corpus.cc:360
const elf_symbols & get_unreferenced_function_symbols() const
Return a list of symbols that are not referenced by any function of corpus::get_functions().
Definition: abg-corpus.cc:427
const elf_symbols & get_unreferenced_variable_symbols() const
Return a list of symbols that are not referenced by any variable of corpus::get_variables().
Definition: abg-corpus.cc:572
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
Definition: abg-corpus.cc:522
~priv()
Destructor of the corpus::priv type.
Definition: abg-corpus.cc:634
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4787
Equality functor for instances of function_decl.
Definition: abg-ir.h:4797
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4756
A comparison functor for pointers to var_decl.
Definition: abg-ir.h:4766