3 // Copyright (C) 2016-2019 Red Hat, Inc.
5 // This file is part of the GNU Application Binary Interface Generic
6 // Analysis and Instrumentation Library (libabigail). This library is
7 // free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option) any
12 // This library is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Lesser Public License for more details.
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this program; see the file COPYING-LGPLV3. If
19 // not, see <http://www.gnu.org/licenses/>.
21 // Author: Dodji Seketeli
23 #ifndef __ABG_SUPPRESSION_H__
24 #define __ABG_SUPPRESSION_H__
26 #include "abg-cxx-compat.h"
28 #include "abg-comparison.h"
33 /// @brief an engine to suppress the parts of the result of comparing
34 /// two sets of ABI artifacts.
36 /// The user specifies the kind of changes between ABI artefact she
37 /// wants to see suppressed. That suppression specification is done
40 /// That INI file is parsed and represented internally using the types
41 /// that are defined in this namespace.
45 using namespace abigail::comparison;
46 using abg_compat::unordered_set;
48 /// Base type of the suppression specifications types.
50 /// This abstracts a suppression specification. It's a way to specify
51 /// how to drop reports about a particular diff node on the floor, if
52 /// it matches the supppression specification.
53 class suppression_base
56 typedef shared_ptr<priv> priv_sptr;
58 // Forbid default constructor
64 suppression_base(const string& label);
66 suppression_base(const string& label,
67 const string& file_name_regex_str,
68 const string& file_name_not_regex_str);
71 get_drops_artifact_from_ir() const;
74 set_drops_artifact_from_ir(bool) const;
77 get_is_artificial() const;
80 set_is_artificial(bool);
86 set_label(const string&);
89 set_file_name_regex_str(const string& regexp);
92 get_file_name_regex_str() const;
95 set_file_name_not_regex_str(const string& regexp);
98 get_file_name_not_regex_str() const;
101 set_soname_regex_str(const string& regexp);
104 get_soname_regex_str() const;
107 set_soname_not_regex_str(const string& regexp);
110 get_soname_not_regex_str() const;
113 suppresses_diff(const diff*) const = 0;
115 virtual ~suppression_base();
116 }; // end class suppression_base
119 read_suppressions(std::istream& input,
120 suppressions_type& suppressions);
123 read_suppressions(const string& file_path,
124 suppressions_type& suppressions);
126 class type_suppression;
128 /// Convenience typedef for a shared pointer to type_suppression.
129 typedef shared_ptr<type_suppression> type_suppression_sptr;
131 /// Convenience typedef for vector of @ref type_suppression_sptr.
132 typedef vector<type_suppression_sptr> type_suppressions_type;
134 /// Abstraction of a type suppression specification.
136 /// Specifies under which condition reports about a type diff node
137 /// should be dropped on the floor.
138 class type_suppression : public suppression_base
141 typedef shared_ptr<priv> priv_sptr;
150 /// The kind of the type the current type suppression is supposed to
162 }; // end enum type_kind
164 /// The different ways through which the type diff has been reached.
167 /// The type diff has been reached (from a function or variable
168 /// change) directly.
169 DIRECT_REACH_KIND = 0,
171 /// The type diff has been reached (from a function or variable
172 /// change) through a pointer.
175 /// The type diff has been reached (from a function or variable
176 /// change) through a reference; you know, like a c++ reference..
177 REFERENCE_REACH_KIND,
179 /// The type diff has been reached (from a function or variable
180 /// change) through either a reference or a pointer.
181 REFERENCE_OR_POINTER_REACH_KIND
182 }; // end enum reach_kind
184 class insertion_range;
185 /// A convenience typedef for a shared pointer to @ref
187 typedef shared_ptr<insertion_range> insertion_range_sptr;
188 /// A convenience typedef for a vector of @ref insertion_range_sptr.
189 typedef vector<insertion_range_sptr> insertion_ranges;
191 type_suppression(const string& label,
192 const string& type_name_regexp,
193 const string& type_name);
195 virtual ~type_suppression();
198 set_type_name_regex_str(const string& name_regex_str);
201 get_type_name_regex_str() const;
204 set_type_name_not_regex_str(const string& name_regex_str);
207 get_type_name_not_regex_str() const;
210 set_type_name(const string& name);
213 get_type_name() const;
216 get_consider_type_kind() const;
219 set_consider_type_kind(bool f);
222 set_type_kind(type_kind k);
225 get_type_kind() const;
228 get_consider_reach_kind() const;
231 set_consider_reach_kind(bool f);
234 get_reach_kind() const;
237 set_reach_kind(reach_kind k);
240 set_data_member_insertion_ranges(const insertion_ranges& r);
242 const insertion_ranges&
243 get_data_member_insertion_ranges() const;
246 get_data_member_insertion_ranges();
248 const unordered_set<string>&
249 get_source_locations_to_keep() const;
251 unordered_set<string>&
252 get_source_locations_to_keep();
255 set_source_locations_to_keep(const unordered_set<string>&);
258 get_source_location_to_keep_regex_str() const;
261 set_source_location_to_keep_regex_str(const string&);
263 const vector<string>&
264 get_changed_enumerator_names() const;
267 set_changed_enumerator_names(const vector<string>&);
270 suppresses_diff(const diff* diff) const;
273 suppresses_type(const type_base_sptr& type,
274 const diff_context_sptr& ctxt) const;
277 suppresses_type(const type_base_sptr& type) const;
280 suppresses_type(const type_base_sptr& type,
281 const scope_decl* type_scope) const;
282 }; // end type_suppression
284 type_suppression_sptr
285 is_type_suppression(const suppression_sptr);
287 /// The abstraction of a range of offsets in which a member of a type
288 /// might get inserted.
289 class type_suppression::insertion_range
294 class integer_boundary;
295 class fn_call_expr_boundary;
297 /// Convenience typedef for a shared_ptr to @ref boundary
298 typedef shared_ptr<boundary> boundary_sptr;
300 /// Convenience typedef for a shared_ptr to a @ref integer_boundary
301 typedef shared_ptr<integer_boundary> integer_boundary_sptr;
303 /// Convenience typedef for a shared_ptr to a @ref
304 /// fn_call_expr_boundary
305 typedef shared_ptr<fn_call_expr_boundary> fn_call_expr_boundary_sptr;
309 typedef shared_ptr<priv> priv_sptr;
316 insertion_range(boundary_sptr begin, boundary_sptr end);
324 static insertion_range::integer_boundary_sptr
325 create_integer_boundary(int value);
327 static insertion_range::fn_call_expr_boundary_sptr
328 create_fn_call_expr_boundary(ini::function_call_expr_sptr);
330 static insertion_range::fn_call_expr_boundary_sptr
331 create_fn_call_expr_boundary(const string&);
334 eval_boundary(boundary_sptr boundary,
335 class_decl_sptr context,
337 }; // end class insertion_range
339 type_suppression::insertion_range::integer_boundary_sptr
340 is_integer_boundary(type_suppression::insertion_range::boundary_sptr);
342 type_suppression::insertion_range::fn_call_expr_boundary_sptr
343 is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
345 /// The abstraction of the boundary of an @ref insertion_range, in the
346 /// context of a @ref type_suppression
347 class type_suppression::insertion_range::boundary
350 typedef shared_ptr<priv> priv_sptr;
357 };// end class type_suppression::insertion_range::boundary
359 /// An @ref insertion_range boundary that is expressed as an integer
360 /// value. That integer value is usually a bit offset.
361 class type_suppression::insertion_range::integer_boundary
362 : public type_suppression::insertion_range::boundary
365 typedef shared_ptr<priv> priv_sptr;
372 integer_boundary(int value);
373 int as_integer() const;
374 operator int() const;
376 }; //end class type_suppression::insertion_range::integer_boundary
378 /// An @ref insertion_range boundary that is expressed as function
379 /// call expression. The (integer) value of that expression is
380 /// usually a bit offset.
381 class type_suppression::insertion_range::fn_call_expr_boundary
382 : public type_suppression::insertion_range::boundary
385 typedef shared_ptr<priv> priv_sptr;
389 fn_call_expr_boundary();
392 fn_call_expr_boundary(ini::function_call_expr_sptr expr);
393 ini::function_call_expr_sptr as_function_call_expr() const;
394 operator ini::function_call_expr_sptr () const;
395 ~fn_call_expr_boundary();
396 }; //end class type_suppression::insertion_range::fn_call_expr_boundary
398 class function_suppression;
400 /// Convenience typedef for a shared pointer to function_suppression.
401 typedef shared_ptr<function_suppression> function_suppression_sptr;
403 /// Convenience typedef for a vector of @ref function_suppression_sptr.
404 typedef vector<function_suppression_sptr> function_suppressions_type;
406 /// Abstraction of a function suppression specification.
408 /// Specifies under which condition reports about a @ref
409 /// function_decl_diff diff node should be dropped on the floor for
410 /// the purpose of reporting.
411 class function_suppression : public suppression_base
414 typedef shared_ptr<priv> priv_sptr;
419 class parameter_spec;
421 /// Convenience typedef for shared_ptr of @ref parameter_spec.
422 typedef shared_ptr<parameter_spec> parameter_spec_sptr;
424 /// Convenience typedef for vector of @ref parameter_spec_sptr.
425 typedef vector<parameter_spec_sptr> parameter_specs_type;
427 /// The kind of change the current function suppression should apply
431 UNDEFINED_CHANGE_KIND,
432 /// A change in a sub-type of the function.
433 FUNCTION_SUBTYPE_CHANGE_KIND = 1,
434 /// The function was added to the second subject of the diff.
435 ADDED_FUNCTION_CHANGE_KIND = 1 << 1,
436 /// The function was deleted from the second subject of the diff.
437 DELETED_FUNCTION_CHANGE_KIND = 1 << 2,
438 /// This represents all the changes possibly described by this
439 /// enum. It's a logical 'OR' of all the change enumerators
441 ALL_CHANGE_KIND = (FUNCTION_SUBTYPE_CHANGE_KIND
442 | ADDED_FUNCTION_CHANGE_KIND
443 | DELETED_FUNCTION_CHANGE_KIND)
446 function_suppression();
448 function_suppression(const string& label,
450 const string& name_regex,
451 const string& return_type_name,
452 const string& return_type_regex,
453 parameter_specs_type& parm_specs,
454 const string& symbol_name,
455 const string& symbol_name_regex,
456 const string& symbol_version,
457 const string& symbol_version_regex_str);
459 virtual ~function_suppression();
462 parse_change_kind(const string&);
465 get_change_kind() const;
468 set_change_kind(change_kind k);
474 set_name(const string&);
477 get_name_regex_str() const;
480 set_name_regex_str(const string&);
483 get_name_not_regex_str() const;
486 set_name_not_regex_str(const string&);
489 get_return_type_name() const;
492 set_return_type_name(const string&);
495 get_return_type_regex_str() const;
498 set_return_type_regex_str(const string& r);
500 const parameter_specs_type&
501 get_parameter_specs() const;
504 set_parameter_specs(parameter_specs_type&);
507 append_parameter_specs(const parameter_spec_sptr);
510 get_symbol_name() const;
513 set_symbol_name(const string& n);
516 get_symbol_name_regex_str() const;
519 set_symbol_name_regex_str(const string&);
522 get_symbol_version() const;
525 set_symbol_version(const string&);
528 get_symbol_version_regex_str() const;
531 set_symbol_version_regex_str(const string&);
534 get_allow_other_aliases() const;
537 set_allow_other_aliases(bool f);
540 suppresses_diff(const diff* diff) const;
543 suppresses_function(const function_decl* fn,
545 const diff_context_sptr ctxt) const;
548 suppresses_function(const function_decl_sptr fn,
550 const diff_context_sptr ctxt) const;
553 suppresses_function_symbol(const elf_symbol* sym,
555 const diff_context_sptr ctxt);
558 suppresses_function_symbol(const elf_symbol_sptr sym,
560 const diff_context_sptr ctxt);
561 }; // end class function_suppression.
563 function_suppression_sptr
564 is_function_suppression(const suppression_sptr);
566 function_suppression::change_kind
567 operator&(function_suppression::change_kind l,
568 function_suppression::change_kind r);
570 function_suppression::change_kind
571 operator|(function_suppression::change_kind l,
572 function_suppression::change_kind r);
574 /// Abstraction of the specification of a function parameter in a
575 /// function suppression specification.
576 class function_suppression::parameter_spec
579 typedef shared_ptr<priv> priv_sptr;
581 friend class function_suppression;
589 parameter_spec(size_t index,
590 const string& type_name,
591 const string& type_name_regex);
600 get_parameter_type_name() const;
603 set_parameter_type_name(const string&);
606 get_parameter_type_name_regex_str() const;
609 set_parameter_type_name_regex_str(const string&);
610 };// end class function_suppression::parameter_spec
612 class variable_suppression;
614 /// A convenience typedef for a shared pointer to @ref
615 /// variable_suppression.
616 typedef shared_ptr<variable_suppression> variable_suppression_sptr;
618 /// A convenience typedef for a vector of @ref
619 /// variable_suppression_sptr.
620 typedef vector<variable_suppression_sptr> variable_suppressions_type;
622 /// The abstraction of a variable suppression specification.
624 /// It specifies under which condition reports about a @ref var_diff
625 /// diff node should be dropped on the floor for the purpose of
627 class variable_suppression : public suppression_base
631 /// The kind of change the current variable suppression should apply
635 UNDEFINED_CHANGE_KIND,
636 /// A change in a sub-type of the variable.
637 VARIABLE_SUBTYPE_CHANGE_KIND = 1,
638 /// The variable was added to the second second subject of the
640 ADDED_VARIABLE_CHANGE_KIND = 1 << 1,
641 /// The variable was deleted from the second subject of the diff.
642 DELETED_VARIABLE_CHANGE_KIND = 1 << 2,
643 /// This represents all the changes possibly described by this
644 /// enum. It's a logical 'OR' of all the change enumerators
646 ALL_CHANGE_KIND = (VARIABLE_SUBTYPE_CHANGE_KIND
647 | ADDED_VARIABLE_CHANGE_KIND
648 | DELETED_VARIABLE_CHANGE_KIND)
653 typedef shared_ptr<priv> priv_sptr;
659 variable_suppression(const string& label = "",
660 const string& name = "",
661 const string& name_regex_str = "",
662 const string& symbol_name = "",
663 const string& symbol_name_regex_str = "",
664 const string& symbol_version = "",
665 const string& symbol_version_regex_str = "",
666 const string& type_name = "",
667 const string& type_name_regex_str = "");
669 virtual ~variable_suppression();
672 parse_change_kind(const string&);
675 get_change_kind() const;
678 set_change_kind(change_kind k);
684 set_name(const string&);
687 get_name_regex_str() const;
690 set_name_regex_str(const string&);
693 get_name_not_regex_str() const;
696 set_name_not_regex_str(const string&);
699 get_symbol_name() const;
702 set_symbol_name(const string&);
705 get_symbol_name_regex_str() const;
708 set_symbol_name_regex_str(const string&);
711 get_symbol_version() const;
714 set_symbol_version(const string&);
717 get_symbol_version_regex_str() const;
720 set_symbol_version_regex_str(const string&);
723 get_type_name() const;
726 set_type_name(const string&);
729 get_type_name_regex_str() const;
732 set_type_name_regex_str(const string&);
735 suppresses_diff(const diff* d) const;
738 suppresses_variable(const var_decl* var,
740 const diff_context_sptr cxt) const;
743 suppresses_variable(const var_decl_sptr var,
745 const diff_context_sptr cxt) const;
748 suppresses_variable_symbol(const elf_symbol* sym,
750 const diff_context_sptr cxt) const;
753 suppresses_variable_symbol(const elf_symbol_sptr fn,
755 const diff_context_sptr cxt) const;
756 }; // end class variable_suppression
758 variable_suppression_sptr
759 is_variable_suppression(const suppression_sptr);
761 variable_suppression::change_kind
762 operator&(variable_suppression::change_kind l,
763 variable_suppression::change_kind r);
765 variable_suppression::change_kind
766 operator|(variable_suppression::change_kind l,
767 variable_suppression::change_kind r);
769 class file_suppression;
771 /// A convenience typedef for a shared_ptr to @ref file_suppression
772 typedef shared_ptr<file_suppression> file_suppression_sptr;
774 /// Abstraction of a suppression specification to avoid loading a
777 /// This can be used by a tool that loads (binary) files, to know
778 /// which file it has to avoid loading.
779 class file_suppression: public suppression_base
782 typedef shared_ptr<priv> priv_sptr;
791 file_suppression(const string& label,
792 const string& file_name_regex,
793 const string& file_name_not_regex);
796 suppresses_diff(const diff* diff) const;
799 suppresses_file(const string& file_path);
801 virtual ~file_suppression();
802 }; // end file_suppression
804 file_suppression_sptr
805 is_file_suppression(const suppression_sptr);
807 file_suppression_sptr
808 file_is_suppressed(const string& file_path,
809 const suppressions_type& suppressions);
812 get_private_types_suppr_spec_label();
815 is_private_type_suppr_spec(const type_suppression&);
818 is_private_type_suppr_spec(const suppression_sptr& s);
819 } // end namespace suppr
821 } // end namespace abigail
823 #endif //__ABG_SUPPRESSION_H__