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