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 
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
1077 corpus::set_symtab(symtab_reader::symtab_sptr symtab)
1078 {priv_->symtab_ = symtab;}
1079 
1080 /// Getter for the symtab object.
1081 ///
1082 /// @return a shared pointer to the symtab object
1083 const symtab_reader::symtab_sptr&
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
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
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 string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
Definition: abg-corpus.cc:1148
void sort_functions()
Sort the set of functions exported by this corpus.
Definition: abg-corpus.cc:1355
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
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
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:319
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 & str() const
Getter for the version name.
Definition: abg-ir.cc:3026
void set_path(const string &)
Set the file path associated to the corpus file.
Definition: abg-corpus.cc:951
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
string & get_format_minor_version_number() const
Getter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:918
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.
void set_needed(const vector< string > &)
Setter of the needed property of the corpus.
Definition: abg-corpus.cc:974
bool operator==(const corpus &) const
Compare the current corpus against another one.
Definition: abg-corpus.cc:1058
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 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
An abstraction helper for type declarations.
Definition: abg-ir.h:1959
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 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
void set_architecture_name(const string &)
Setter for the architecture name of the corpus.
Definition: abg-corpus.cc:1018
A comparison functor for pointers to var_decl.
Definition: abg-ir.h:4765
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:733
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:24
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:701
virtual const variables & get_variables() const
Return the public decl table of the global variables of the current corpus.
Definition: abg-corpus.cc:1377
void set_format_minor_version_number(const string &)
Setter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:927
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
virtual const functions & get_functions() const
Return the functions public decl table of the current corpus.
Definition: abg-corpus.cc:1323
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
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
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
virtual const corpus::functions & get_functions() const
Get the functions exported by the corpora of the current corpus group.
Definition: abg-corpus.cc:1832
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 elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
Definition: abg-corpus.cc:479
void sort_variables()
Sort the set of variables exported by this corpus.
Definition: abg-corpus.cc:1385
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
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 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
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:134
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4960
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:1986
vector< string > & get_sym_ids_of_vars_to_keep()
Getter for the vector of variable symbol IDs to keep.
Definition: abg-corpus.cc:1520
void set_soname(const string &)
Setter for the soname property of the corpus.
Definition: abg-corpus.cc:996
string & get_format_major_version_number() const
Getter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:901
This contains the declarations for the symtab reader.
const corpora_type & get_corpora() const
Getter of the vector of corpora held by the current corpus_group.
Definition: abg-corpus.cc:1794
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
Abstracts a variable declaration.
Definition: abg-ir.h:2943
A functor to compare instances of var_decl base on their qualified names.
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
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
Definition: abg-ir.h:890
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
Definition: abg-corpus.cc:962
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 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
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1645
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
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4331
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
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
Toplevel namespace for libabigail.
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
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
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:44
This contains the private implementation of the suppression engine of libabigail. ...
~priv()
Destructor of the corpus::priv type.
Definition: abg-corpus.cc:634
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
Abstraction for a function declaration.
Definition: abg-ir.h:3046
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
void add_corpus(const corpus_sptr &)
Add a new corpus to the current instance of corpus_group.
Definition: abg-corpus.cc:1743
Types of the main internal representation of libabigail.
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 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
vector< string > strings_type
A convenience typedef for std::vector.
Definition: abg-corpus.h:28
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4786
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
void add(const translation_unit_sptr &)
Add a translation unit to the current ABI Corpus.
Definition: abg-corpus.cc:681
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
The type of the private data of corpus::exported_decls_builder type.
This is a type that aggregates maps of all the kinds of types that are supported by libabigail...
Definition: abg-ir.h:584
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
Abstraction of an elf symbol.
Definition: abg-ir.h:908
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:139
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
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 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
virtual bool is_empty() const
Test if the current corpus group is empty.
Definition: abg-corpus.cc:1819
void drop_translation_units()
Erase the translation units contained in this in-memory object.
Definition: abg-corpus.cc:726
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:872
const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
Definition: abg-corpus.cc:335
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition: abg-fwd.h:88
#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
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3792
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 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
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 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
vector< var_decl * > variables
Convenience typedef for std::vector
Definition: abg-corpus.h:34
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:303
const symtab_reader::symtab_sptr & get_symtab() const
Getter for the symtab object.
Definition: abg-corpus.cc:1084
string & get_path() const
Get the file path associated to the corpus file.
Definition: abg-corpus.cc:939
const corpus_sptr get_main_corpus() const
Getter of the first corpus added to this Group.
Definition: abg-corpus.cc:1801
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 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
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1603
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
Equality functor for instances of function_decl.
Definition: abg-ir.h:4796
vector< string > & get_sym_ids_of_fns_to_keep()
Getter for the vector of function symbol IDs to keep.
Definition: abg-corpus.cc:1480
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4755
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2045
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:656
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1617
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
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 set_origin(origin)
Setter for the origin of the corpus.
Definition: abg-corpus.cc:893
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
The abstraction of an interned string.
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
void set_format_major_version_number(const string &)
Setter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:909
vector< function_decl * > functions
Convenience typedef for std::vector
Definition: abg-corpus.h:31
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
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1179
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:850
The private data of the corpus type.
Abstraction of a group of corpora.
Definition: abg-corpus.h:352
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
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:886
The private data and functions of the abigail::ir::corpus type.
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
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
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
const string & get_soname()
Getter for the soname property of the corpus.
Definition: abg-corpus.cc:985
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1631
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
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
Definition: abg-corpus.cc:1077
virtual ~corpus_group()
Desctructor of the corpus_group type.
Definition: abg-corpus.cc:1736
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
Definition: abg-corpus.cc:1007
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
Definition: abg-corpus.cc:1091
bool has_corpus(const string &)
Test if a corpus of a given path has been added to the group.
Definition: abg-corpus.cc:1782
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
bool do_log() const
Test if logging was requested.
Definition: abg-corpus.cc:663
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
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr.
Definition: abg-corpus.h:36
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