Support the "name_not_regexp" property in the [suppress_type] section
[platform/upstream/libabigail.git] / include / abg-suppression.h
1 // -*- Mode: C++ -*-
2 //
3 // Copyright (C) 2016-2019 Red Hat, Inc.
4 //
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
10 // later version.
11
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.
16
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/>.
20 //
21 // Author: Dodji Seketeli
22
23 #ifndef __ABG_SUPPRESSION_H__
24 #define __ABG_SUPPRESSION_H__
25
26 #include "abg-cxx-compat.h"
27 #include "abg-ini.h"
28 #include "abg-comparison.h"
29
30 namespace abigail
31 {
32
33 /// @brief an engine to suppress the parts of the result of comparing
34 /// two sets of ABI artifacts.
35 ///
36 /// The user specifies the kind of changes between ABI artefact she
37 /// wants to see suppressed.  That suppression specification is done
38 /// in an INI format.
39 ///
40 /// That INI file is parsed and represented internally using the types
41 /// that are defined in this namespace.
42 namespace suppr
43 {
44
45 using namespace abigail::comparison;
46 using abg_compat::unordered_set;
47
48 /// Base type of the suppression specifications types.
49 ///
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
54 {
55   class priv;
56   typedef shared_ptr<priv> priv_sptr;
57
58   // Forbid default constructor
59   suppression_base();
60
61 public:
62   priv_sptr priv_;
63
64   suppression_base(const string& label);
65
66   suppression_base(const string& label,
67                    const string& file_name_regex_str,
68                    const string& file_name_not_regex_str);
69
70   bool
71   get_drops_artifact_from_ir() const;
72
73   void
74   set_drops_artifact_from_ir(bool) const;
75
76   bool
77   get_is_artificial() const;
78
79   void
80   set_is_artificial(bool);
81
82   const string
83   get_label() const;
84
85   void
86   set_label(const string&);
87
88   void
89   set_file_name_regex_str(const string& regexp);
90
91   const string&
92   get_file_name_regex_str() const;
93
94   void
95   set_file_name_not_regex_str(const string& regexp);
96
97   const string&
98   get_file_name_not_regex_str() const;
99
100   void
101   set_soname_regex_str(const string& regexp);
102
103   const string&
104   get_soname_regex_str() const;
105
106   void
107   set_soname_not_regex_str(const string& regexp);
108
109   const string&
110   get_soname_not_regex_str() const;
111
112   virtual bool
113   suppresses_diff(const diff*) const = 0;
114
115   virtual ~suppression_base();
116 }; // end class suppression_base
117
118 void
119 read_suppressions(std::istream& input,
120                   suppressions_type& suppressions);
121
122 void
123 read_suppressions(const string& file_path,
124                   suppressions_type& suppressions);
125
126 class type_suppression;
127
128 /// Convenience typedef for a shared pointer to type_suppression.
129 typedef shared_ptr<type_suppression> type_suppression_sptr;
130
131 /// Convenience typedef for vector of @ref type_suppression_sptr.
132 typedef vector<type_suppression_sptr> type_suppressions_type;
133
134 /// Abstraction of a type suppression specification.
135 ///
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
139 {
140   class priv;
141   typedef shared_ptr<priv> priv_sptr;
142
143   // Forbid this;
144   type_suppression();
145
146 public:
147
148   priv_sptr priv_;
149
150   /// The kind of the type the current type suppression is supposed to
151   /// be about.
152   enum type_kind
153   {
154     UNKNOWN_TYPE_KIND,
155     CLASS_TYPE_KIND,
156     STRUCT_TYPE_KIND,
157     UNION_TYPE_KIND,
158     ENUM_TYPE_KIND,
159     ARRAY_TYPE_KIND,
160     TYPEDEF_TYPE_KIND,
161     BUILTIN_TYPE_KIND
162   }; // end enum type_kind
163
164   /// The different ways through which the type diff has been reached.
165   enum reach_kind
166   {
167     /// The type diff has been reached (from a function or variable
168     /// change) directly.
169     DIRECT_REACH_KIND = 0,
170
171     /// The type diff has been reached (from a function or variable
172     /// change) through a pointer.
173     POINTER_REACH_KIND,
174
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,
178
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
183
184   class insertion_range;
185   /// A convenience typedef for a shared pointer to @ref
186   /// insertion_range.
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;
190
191   type_suppression(const string& label,
192                    const string& type_name_regexp,
193                    const string& type_name);
194
195   virtual ~type_suppression();
196
197   void
198   set_type_name_regex_str(const string& name_regex_str);
199
200   const string&
201   get_type_name_regex_str() const;
202
203   void
204   set_type_name_not_regex_str(const string& name_regex_str);
205
206   const string&
207   get_type_name_not_regex_str() const;
208
209   void
210   set_type_name(const string& name);
211
212   const string&
213   get_type_name() const;
214
215   bool
216   get_consider_type_kind() const;
217
218   void
219   set_consider_type_kind(bool f);
220
221   void
222   set_type_kind(type_kind k);
223
224   type_kind
225   get_type_kind() const;
226
227   bool
228   get_consider_reach_kind() const;
229
230   void
231   set_consider_reach_kind(bool f);
232
233   reach_kind
234   get_reach_kind() const;
235
236   void
237   set_reach_kind(reach_kind k);
238
239   void
240   set_data_member_insertion_ranges(const insertion_ranges& r);
241
242   const insertion_ranges&
243   get_data_member_insertion_ranges() const;
244
245   insertion_ranges&
246   get_data_member_insertion_ranges();
247
248   const unordered_set<string>&
249   get_source_locations_to_keep() const;
250
251   unordered_set<string>&
252   get_source_locations_to_keep();
253
254   void
255   set_source_locations_to_keep(const unordered_set<string>&);
256
257   const string&
258   get_source_location_to_keep_regex_str() const;
259
260   void
261   set_source_location_to_keep_regex_str(const string&);
262
263   const vector<string>&
264   get_changed_enumerator_names() const;
265
266   void
267   set_changed_enumerator_names(const vector<string>&);
268
269   virtual bool
270   suppresses_diff(const diff* diff) const;
271
272   bool
273   suppresses_type(const type_base_sptr& type,
274                   const diff_context_sptr& ctxt) const;
275
276   bool
277   suppresses_type(const type_base_sptr& type) const;
278
279   bool
280   suppresses_type(const type_base_sptr& type,
281                   const scope_decl* type_scope) const;
282 }; // end type_suppression
283
284 type_suppression_sptr
285 is_type_suppression(const suppression_sptr);
286
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
290 {
291 public:
292
293   class boundary;
294   class integer_boundary;
295   class fn_call_expr_boundary;
296
297   /// Convenience typedef for a shared_ptr to @ref boundary
298   typedef shared_ptr<boundary> boundary_sptr;
299
300   /// Convenience typedef for a shared_ptr to a @ref integer_boundary
301   typedef shared_ptr<integer_boundary> integer_boundary_sptr;
302
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;
306
307 private:
308   struct priv;
309   typedef shared_ptr<priv> priv_sptr;
310
311   priv_sptr priv_;
312
313 public:
314   insertion_range();
315
316   insertion_range(boundary_sptr begin, boundary_sptr end);
317
318   boundary_sptr
319   begin() const;
320
321  boundary_sptr
322   end() const;
323
324   static insertion_range::integer_boundary_sptr
325   create_integer_boundary(int value);
326
327   static insertion_range::fn_call_expr_boundary_sptr
328   create_fn_call_expr_boundary(ini::function_call_expr_sptr);
329
330   static insertion_range::fn_call_expr_boundary_sptr
331   create_fn_call_expr_boundary(const string&);
332
333   static bool
334   eval_boundary(boundary_sptr   boundary,
335                 class_decl_sptr context,
336                 ssize_t&        value);
337 }; // end class insertion_range
338
339 type_suppression::insertion_range::integer_boundary_sptr
340 is_integer_boundary(type_suppression::insertion_range::boundary_sptr);
341
342 type_suppression::insertion_range::fn_call_expr_boundary_sptr
343 is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
344
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
348 {
349   struct priv;
350   typedef shared_ptr<priv> priv_sptr;
351
352   priv_sptr priv_;
353
354 public:
355   boundary();
356   virtual ~boundary();
357 };// end class type_suppression::insertion_range::boundary
358
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
363 {
364   struct priv;
365   typedef shared_ptr<priv> priv_sptr;
366
367   priv_sptr priv_;
368
369   integer_boundary();
370
371 public:
372   integer_boundary(int value);
373   int as_integer() const;
374   operator int() const;
375   ~integer_boundary();
376 }; //end class type_suppression::insertion_range::integer_boundary
377
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
383 {
384   struct priv;
385   typedef shared_ptr<priv> priv_sptr;
386
387   priv_sptr priv_;
388
389   fn_call_expr_boundary();
390
391 public:
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
397
398 class function_suppression;
399
400 /// Convenience typedef for a shared pointer to function_suppression.
401 typedef shared_ptr<function_suppression> function_suppression_sptr;
402
403 /// Convenience typedef for a vector of @ref function_suppression_sptr.
404 typedef vector<function_suppression_sptr> function_suppressions_type;
405
406 /// Abstraction of a function suppression specification.
407 ///
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
412 {
413   struct priv;
414   typedef shared_ptr<priv> priv_sptr;
415
416 public:
417
418   priv_sptr priv_;
419   class parameter_spec;
420
421   /// Convenience typedef for shared_ptr of @ref parameter_spec.
422   typedef shared_ptr<parameter_spec> parameter_spec_sptr;
423
424   /// Convenience typedef for vector of @ref parameter_spec_sptr.
425   typedef vector<parameter_spec_sptr> parameter_specs_type;
426
427   /// The kind of change the current function suppression should apply
428   /// to.
429   enum change_kind
430   {
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
440     /// above.
441     ALL_CHANGE_KIND = (FUNCTION_SUBTYPE_CHANGE_KIND
442                        | ADDED_FUNCTION_CHANGE_KIND
443                        | DELETED_FUNCTION_CHANGE_KIND)
444   };
445
446   function_suppression();
447
448   function_suppression(const string&            label,
449                        const string&            name,
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);
458
459   virtual ~function_suppression();
460
461   static change_kind
462   parse_change_kind(const string&);
463
464   change_kind
465   get_change_kind() const;
466
467   void
468   set_change_kind(change_kind k);
469
470   const string&
471   get_name() const;
472
473   void
474   set_name(const string&);
475
476   const string&
477   get_name_regex_str() const;
478
479   void
480   set_name_regex_str(const string&);
481
482   const string&
483   get_name_not_regex_str() const;
484
485   void
486   set_name_not_regex_str(const string&);
487
488   const string&
489   get_return_type_name() const;
490
491   void
492   set_return_type_name(const string&);
493
494   const string&
495   get_return_type_regex_str() const;
496
497   void
498   set_return_type_regex_str(const string& r);
499
500   const parameter_specs_type&
501   get_parameter_specs() const;
502
503   void
504   set_parameter_specs(parameter_specs_type&);
505
506   void
507   append_parameter_specs(const parameter_spec_sptr);
508
509   const string&
510   get_symbol_name() const;
511
512   void
513   set_symbol_name(const string& n);
514
515   const string&
516   get_symbol_name_regex_str() const;
517
518   void
519   set_symbol_name_regex_str(const string&);
520
521   const string&
522   get_symbol_version() const;
523
524   void
525   set_symbol_version(const string&);
526
527   const string&
528   get_symbol_version_regex_str() const;
529
530   void
531   set_symbol_version_regex_str(const string&);
532
533   bool
534   get_allow_other_aliases() const;
535
536   void
537   set_allow_other_aliases(bool f);
538
539   virtual bool
540   suppresses_diff(const diff* diff) const;
541
542   bool
543   suppresses_function(const function_decl* fn,
544                       change_kind k,
545                       const diff_context_sptr ctxt) const;
546
547   bool
548   suppresses_function(const function_decl_sptr fn,
549                       change_kind k,
550                       const diff_context_sptr ctxt) const;
551
552   bool
553   suppresses_function_symbol(const elf_symbol* sym,
554                              change_kind k,
555                              const diff_context_sptr ctxt);
556
557   bool
558   suppresses_function_symbol(const elf_symbol_sptr sym,
559                              change_kind k,
560                              const diff_context_sptr ctxt);
561 }; // end class function_suppression.
562
563 function_suppression_sptr
564 is_function_suppression(const suppression_sptr);
565
566 function_suppression::change_kind
567 operator&(function_suppression::change_kind l,
568           function_suppression::change_kind r);
569
570 function_suppression::change_kind
571 operator|(function_suppression::change_kind l,
572           function_suppression::change_kind r);
573
574 /// Abstraction of the specification of a function parameter in a
575 /// function suppression specification.
576 class function_suppression::parameter_spec
577 {
578   class priv;
579   typedef shared_ptr<priv> priv_sptr;
580
581   friend class function_suppression;
582
583   priv_sptr priv_;
584
585   // Forbid this.
586   parameter_spec();
587
588 public:
589   parameter_spec(size_t index,
590                  const string& type_name,
591                  const string& type_name_regex);
592
593   size_t
594   get_index() const;
595
596   void
597   set_index(size_t);
598
599   const string&
600   get_parameter_type_name() const;
601
602   void
603   set_parameter_type_name(const string&);
604
605   const string&
606   get_parameter_type_name_regex_str() const;
607
608   void
609   set_parameter_type_name_regex_str(const string&);
610 };// end class function_suppression::parameter_spec
611
612 class variable_suppression;
613
614 /// A convenience typedef for a shared pointer to @ref
615 /// variable_suppression.
616 typedef shared_ptr<variable_suppression> variable_suppression_sptr;
617
618 /// A convenience typedef for a vector of @ref
619 /// variable_suppression_sptr.
620 typedef vector<variable_suppression_sptr> variable_suppressions_type;
621
622 /// The abstraction of a variable suppression specification.
623 ///
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
626 /// reporting.
627 class variable_suppression : public suppression_base
628 {
629 public:
630
631   /// The kind of change the current variable suppression should apply
632   /// to.
633   enum change_kind
634   {
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
639     /// diff.
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
645     /// above.
646     ALL_CHANGE_KIND = (VARIABLE_SUBTYPE_CHANGE_KIND
647                        | ADDED_VARIABLE_CHANGE_KIND
648                        | DELETED_VARIABLE_CHANGE_KIND)
649   };
650
651 private:
652   struct priv;
653   typedef shared_ptr<priv> priv_sptr;
654
655 public:
656
657   priv_sptr priv_;
658
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 = "");
668
669   virtual ~variable_suppression();
670
671   static change_kind
672   parse_change_kind(const string&);
673
674   change_kind
675   get_change_kind() const;
676
677   void
678   set_change_kind(change_kind k);
679
680   const string&
681   get_name() const;
682
683   void
684   set_name(const string&);
685
686   const string&
687   get_name_regex_str() const;
688
689   void
690   set_name_regex_str(const string&);
691
692   const string&
693   get_name_not_regex_str() const;
694
695   void
696   set_name_not_regex_str(const string&);
697
698   const string&
699   get_symbol_name() const;
700
701   void
702   set_symbol_name(const string&);
703
704   const string&
705   get_symbol_name_regex_str() const;
706
707   void
708   set_symbol_name_regex_str(const string&);
709
710   const string&
711   get_symbol_version() const;
712
713   void
714   set_symbol_version(const string&);
715
716   const string&
717   get_symbol_version_regex_str() const;
718
719   void
720   set_symbol_version_regex_str(const string&);
721
722   const string&
723   get_type_name() const;
724
725   void
726   set_type_name(const string&);
727
728   const string&
729   get_type_name_regex_str() const;
730
731   void
732   set_type_name_regex_str(const string&);
733
734   bool
735   suppresses_diff(const diff* d) const;
736
737   bool
738   suppresses_variable(const var_decl* var,
739                       change_kind k,
740                       const diff_context_sptr cxt) const;
741
742   bool
743   suppresses_variable(const var_decl_sptr var,
744                       change_kind k,
745                       const diff_context_sptr cxt) const;
746
747   bool
748   suppresses_variable_symbol(const elf_symbol* sym,
749                              change_kind k,
750                              const diff_context_sptr cxt) const;
751
752   bool
753   suppresses_variable_symbol(const elf_symbol_sptr fn,
754                              change_kind k,
755                              const diff_context_sptr cxt) const;
756 }; // end class variable_suppression
757
758 variable_suppression_sptr
759 is_variable_suppression(const suppression_sptr);
760
761 variable_suppression::change_kind
762 operator&(variable_suppression::change_kind l,
763           variable_suppression::change_kind r);
764
765 variable_suppression::change_kind
766 operator|(variable_suppression::change_kind l,
767           variable_suppression::change_kind r);
768
769 class file_suppression;
770
771 /// A convenience typedef for a shared_ptr to @ref file_suppression
772 typedef shared_ptr<file_suppression> file_suppression_sptr;
773
774 /// Abstraction of a suppression specification to avoid loading a
775 /// file.
776 ///
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
780 {
781   class priv;
782   typedef shared_ptr<priv> priv_sptr;
783
784   priv_sptr priv_;
785
786   // Forbid this
787   file_suppression();
788
789 public:
790
791   file_suppression(const string& label,
792                    const string& file_name_regex,
793                    const string& file_name_not_regex);
794
795   virtual bool
796   suppresses_diff(const diff* diff) const;
797
798   bool
799   suppresses_file(const string& file_path);
800
801   virtual ~file_suppression();
802 }; // end file_suppression
803
804 file_suppression_sptr
805 is_file_suppression(const suppression_sptr);
806
807 file_suppression_sptr
808 file_is_suppressed(const string& file_path,
809                    const suppressions_type& suppressions);
810
811 const char*
812 get_private_types_suppr_spec_label();
813
814 bool
815 is_private_type_suppr_spec(const type_suppression&);
816
817 bool
818 is_private_type_suppr_spec(const suppression_sptr& s);
819 } // end namespace suppr
820
821 } // end namespace abigail
822
823 #endif //__ABG_SUPPRESSION_H__