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(const string& name);
207 get_type_name() const;
210 get_consider_type_kind() const;
213 set_consider_type_kind(bool f);
216 set_type_kind(type_kind k);
219 get_type_kind() const;
222 get_consider_reach_kind() const;
225 set_consider_reach_kind(bool f);
228 get_reach_kind() const;
231 set_reach_kind(reach_kind k);
234 set_data_member_insertion_ranges(const insertion_ranges& r);
236 const insertion_ranges&
237 get_data_member_insertion_ranges() const;
240 get_data_member_insertion_ranges();
242 const unordered_set<string>&
243 get_source_locations_to_keep() const;
245 unordered_set<string>&
246 get_source_locations_to_keep();
249 set_source_locations_to_keep(const unordered_set<string>&);
252 get_source_location_to_keep_regex_str() const;
255 set_source_location_to_keep_regex_str(const string&);
257 const vector<string>&
258 get_changed_enumerator_names() const;
261 set_changed_enumerator_names(const vector<string>&);
264 suppresses_diff(const diff* diff) const;
267 suppresses_type(const type_base_sptr& type,
268 const diff_context_sptr& ctxt) const;
271 suppresses_type(const type_base_sptr& type) const;
274 suppresses_type(const type_base_sptr& type,
275 const scope_decl* type_scope) const;
276 }; // end type_suppression
278 type_suppression_sptr
279 is_type_suppression(const suppression_sptr);
281 /// The abstraction of a range of offsets in which a member of a type
282 /// might get inserted.
283 class type_suppression::insertion_range
288 class integer_boundary;
289 class fn_call_expr_boundary;
291 /// Convenience typedef for a shared_ptr to @ref boundary
292 typedef shared_ptr<boundary> boundary_sptr;
294 /// Convenience typedef for a shared_ptr to a @ref integer_boundary
295 typedef shared_ptr<integer_boundary> integer_boundary_sptr;
297 /// Convenience typedef for a shared_ptr to a @ref
298 /// fn_call_expr_boundary
299 typedef shared_ptr<fn_call_expr_boundary> fn_call_expr_boundary_sptr;
303 typedef shared_ptr<priv> priv_sptr;
310 insertion_range(boundary_sptr begin, boundary_sptr end);
318 static insertion_range::integer_boundary_sptr
319 create_integer_boundary(int value);
321 static insertion_range::fn_call_expr_boundary_sptr
322 create_fn_call_expr_boundary(ini::function_call_expr_sptr);
324 static insertion_range::fn_call_expr_boundary_sptr
325 create_fn_call_expr_boundary(const string&);
328 eval_boundary(boundary_sptr boundary,
329 class_decl_sptr context,
331 }; // end class insertion_range
333 type_suppression::insertion_range::integer_boundary_sptr
334 is_integer_boundary(type_suppression::insertion_range::boundary_sptr);
336 type_suppression::insertion_range::fn_call_expr_boundary_sptr
337 is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
339 /// The abstraction of the boundary of an @ref insertion_range, in the
340 /// context of a @ref type_suppression
341 class type_suppression::insertion_range::boundary
344 typedef shared_ptr<priv> priv_sptr;
351 };// end class type_suppression::insertion_range::boundary
353 /// An @ref insertion_range boundary that is expressed as an integer
354 /// value. That integer value is usually a bit offset.
355 class type_suppression::insertion_range::integer_boundary
356 : public type_suppression::insertion_range::boundary
359 typedef shared_ptr<priv> priv_sptr;
366 integer_boundary(int value);
367 int as_integer() const;
368 operator int() const;
370 }; //end class type_suppression::insertion_range::integer_boundary
372 /// An @ref insertion_range boundary that is expressed as function
373 /// call expression. The (integer) value of that expression is
374 /// usually a bit offset.
375 class type_suppression::insertion_range::fn_call_expr_boundary
376 : public type_suppression::insertion_range::boundary
379 typedef shared_ptr<priv> priv_sptr;
383 fn_call_expr_boundary();
386 fn_call_expr_boundary(ini::function_call_expr_sptr expr);
387 ini::function_call_expr_sptr as_function_call_expr() const;
388 operator ini::function_call_expr_sptr () const;
389 ~fn_call_expr_boundary();
390 }; //end class type_suppression::insertion_range::fn_call_expr_boundary
392 class function_suppression;
394 /// Convenience typedef for a shared pointer to function_suppression.
395 typedef shared_ptr<function_suppression> function_suppression_sptr;
397 /// Convenience typedef for a vector of @ref function_suppression_sptr.
398 typedef vector<function_suppression_sptr> function_suppressions_type;
400 /// Abstraction of a function suppression specification.
402 /// Specifies under which condition reports about a @ref
403 /// function_decl_diff diff node should be dropped on the floor for
404 /// the purpose of reporting.
405 class function_suppression : public suppression_base
408 typedef shared_ptr<priv> priv_sptr;
413 class parameter_spec;
415 /// Convenience typedef for shared_ptr of @ref parameter_spec.
416 typedef shared_ptr<parameter_spec> parameter_spec_sptr;
418 /// Convenience typedef for vector of @ref parameter_spec_sptr.
419 typedef vector<parameter_spec_sptr> parameter_specs_type;
421 /// The kind of change the current function suppression should apply
425 UNDEFINED_CHANGE_KIND,
426 /// A change in a sub-type of the function.
427 FUNCTION_SUBTYPE_CHANGE_KIND = 1,
428 /// The function was added to the second subject of the diff.
429 ADDED_FUNCTION_CHANGE_KIND = 1 << 1,
430 /// The function was deleted from the second subject of the diff.
431 DELETED_FUNCTION_CHANGE_KIND = 1 << 2,
432 /// This represents all the changes possibly described by this
433 /// enum. It's a logical 'OR' of all the change enumerators
435 ALL_CHANGE_KIND = (FUNCTION_SUBTYPE_CHANGE_KIND
436 | ADDED_FUNCTION_CHANGE_KIND
437 | DELETED_FUNCTION_CHANGE_KIND)
440 function_suppression();
442 function_suppression(const string& label,
444 const string& name_regex,
445 const string& return_type_name,
446 const string& return_type_regex,
447 parameter_specs_type& parm_specs,
448 const string& symbol_name,
449 const string& symbol_name_regex,
450 const string& symbol_version,
451 const string& symbol_version_regex_str);
453 virtual ~function_suppression();
456 parse_change_kind(const string&);
459 get_change_kind() const;
462 set_change_kind(change_kind k);
468 set_name(const string&);
471 get_name_regex_str() const;
474 set_name_regex_str(const string&);
477 get_name_not_regex_str() const;
480 set_name_not_regex_str(const string&);
483 get_return_type_name() const;
486 set_return_type_name(const string&);
489 get_return_type_regex_str() const;
492 set_return_type_regex_str(const string& r);
494 const parameter_specs_type&
495 get_parameter_specs() const;
498 set_parameter_specs(parameter_specs_type&);
501 append_parameter_specs(const parameter_spec_sptr);
504 get_symbol_name() const;
507 set_symbol_name(const string& n);
510 get_symbol_name_regex_str() const;
513 set_symbol_name_regex_str(const string&);
516 get_symbol_version() const;
519 set_symbol_version(const string&);
522 get_symbol_version_regex_str() const;
525 set_symbol_version_regex_str(const string&);
528 get_allow_other_aliases() const;
531 set_allow_other_aliases(bool f);
534 suppresses_diff(const diff* diff) const;
537 suppresses_function(const function_decl* fn,
539 const diff_context_sptr ctxt) const;
542 suppresses_function(const function_decl_sptr fn,
544 const diff_context_sptr ctxt) const;
547 suppresses_function_symbol(const elf_symbol* sym,
549 const diff_context_sptr ctxt);
552 suppresses_function_symbol(const elf_symbol_sptr sym,
554 const diff_context_sptr ctxt);
555 }; // end class function_suppression.
557 function_suppression_sptr
558 is_function_suppression(const suppression_sptr);
560 function_suppression::change_kind
561 operator&(function_suppression::change_kind l,
562 function_suppression::change_kind r);
564 function_suppression::change_kind
565 operator|(function_suppression::change_kind l,
566 function_suppression::change_kind r);
568 /// Abstraction of the specification of a function parameter in a
569 /// function suppression specification.
570 class function_suppression::parameter_spec
573 typedef shared_ptr<priv> priv_sptr;
575 friend class function_suppression;
583 parameter_spec(size_t index,
584 const string& type_name,
585 const string& type_name_regex);
594 get_parameter_type_name() const;
597 set_parameter_type_name(const string&);
600 get_parameter_type_name_regex_str() const;
603 set_parameter_type_name_regex_str(const string&);
604 };// end class function_suppression::parameter_spec
606 class variable_suppression;
608 /// A convenience typedef for a shared pointer to @ref
609 /// variable_suppression.
610 typedef shared_ptr<variable_suppression> variable_suppression_sptr;
612 /// A convenience typedef for a vector of @ref
613 /// variable_suppression_sptr.
614 typedef vector<variable_suppression_sptr> variable_suppressions_type;
616 /// The abstraction of a variable suppression specification.
618 /// It specifies under which condition reports about a @ref var_diff
619 /// diff node should be dropped on the floor for the purpose of
621 class variable_suppression : public suppression_base
625 /// The kind of change the current variable suppression should apply
629 UNDEFINED_CHANGE_KIND,
630 /// A change in a sub-type of the variable.
631 VARIABLE_SUBTYPE_CHANGE_KIND = 1,
632 /// The variable was added to the second second subject of the
634 ADDED_VARIABLE_CHANGE_KIND = 1 << 1,
635 /// The variable was deleted from the second subject of the diff.
636 DELETED_VARIABLE_CHANGE_KIND = 1 << 2,
637 /// This represents all the changes possibly described by this
638 /// enum. It's a logical 'OR' of all the change enumerators
640 ALL_CHANGE_KIND = (VARIABLE_SUBTYPE_CHANGE_KIND
641 | ADDED_VARIABLE_CHANGE_KIND
642 | DELETED_VARIABLE_CHANGE_KIND)
647 typedef shared_ptr<priv> priv_sptr;
653 variable_suppression(const string& label = "",
654 const string& name = "",
655 const string& name_regex_str = "",
656 const string& symbol_name = "",
657 const string& symbol_name_regex_str = "",
658 const string& symbol_version = "",
659 const string& symbol_version_regex_str = "",
660 const string& type_name = "",
661 const string& type_name_regex_str = "");
663 virtual ~variable_suppression();
666 parse_change_kind(const string&);
669 get_change_kind() const;
672 set_change_kind(change_kind k);
678 set_name(const string&);
681 get_name_regex_str() const;
684 set_name_regex_str(const string&);
687 get_name_not_regex_str() const;
690 set_name_not_regex_str(const string&);
693 get_symbol_name() const;
696 set_symbol_name(const string&);
699 get_symbol_name_regex_str() const;
702 set_symbol_name_regex_str(const string&);
705 get_symbol_version() const;
708 set_symbol_version(const string&);
711 get_symbol_version_regex_str() const;
714 set_symbol_version_regex_str(const string&);
717 get_type_name() const;
720 set_type_name(const string&);
723 get_type_name_regex_str() const;
726 set_type_name_regex_str(const string&);
729 suppresses_diff(const diff* d) const;
732 suppresses_variable(const var_decl* var,
734 const diff_context_sptr cxt) const;
737 suppresses_variable(const var_decl_sptr var,
739 const diff_context_sptr cxt) const;
742 suppresses_variable_symbol(const elf_symbol* sym,
744 const diff_context_sptr cxt) const;
747 suppresses_variable_symbol(const elf_symbol_sptr fn,
749 const diff_context_sptr cxt) const;
750 }; // end class variable_suppression
752 variable_suppression_sptr
753 is_variable_suppression(const suppression_sptr);
755 variable_suppression::change_kind
756 operator&(variable_suppression::change_kind l,
757 variable_suppression::change_kind r);
759 variable_suppression::change_kind
760 operator|(variable_suppression::change_kind l,
761 variable_suppression::change_kind r);
763 class file_suppression;
765 /// A convenience typedef for a shared_ptr to @ref file_suppression
766 typedef shared_ptr<file_suppression> file_suppression_sptr;
768 /// Abstraction of a suppression specification to avoid loading a
771 /// This can be used by a tool that loads (binary) files, to know
772 /// which file it has to avoid loading.
773 class file_suppression: public suppression_base
776 typedef shared_ptr<priv> priv_sptr;
785 file_suppression(const string& label,
786 const string& file_name_regex,
787 const string& file_name_not_regex);
790 suppresses_diff(const diff* diff) const;
793 suppresses_file(const string& file_path);
795 virtual ~file_suppression();
796 }; // end file_suppression
798 file_suppression_sptr
799 is_file_suppression(const suppression_sptr);
801 file_suppression_sptr
802 file_is_suppressed(const string& file_path,
803 const suppressions_type& suppressions);
806 get_private_types_suppr_spec_label();
809 is_private_type_suppr_spec(const type_suppression&);
812 is_private_type_suppr_spec(const suppression_sptr& s);
813 } // end namespace suppr
815 } // end namespace abigail
817 #endif //__ABG_SUPPRESSION_H__