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