• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#########
2Concepts
3#########
4
5.. _abi_artifacts_label:
6
7ABI artifacts
8=============
9
10An ABI artifact is a relevant part of the ABI of a shared library or
11program.  Examples of ABI artifacts are exported types, variables,
12functions, or `ELF`_ symbols exported by a shared library.
13
14The set of ABI artifact for a binary is called an ABI Corpus.
15
16.. _harmfulchangeconcept_label:
17
18Harmful changes
19===============
20
21A change in the diff report is considered harmful if it might cause
22ABI compatibility issues.  That is, it might prevent an application
23dynamically linked against a given version of a library to keep
24working with the changed subsequent versions of the same library.
25
26.. _harmlesschangeconcept_label:
27
28Harmless changes
29================
30
31A change in the diff report is considered harmless if it will not
32cause any ABI compatibility issue.  That is, it will not prevent an
33application dynamically linked against given version of a library to
34keep working with the changed subsequent versions of the same library.
35
36By default, ``abidiff`` filters harmless changes from the diff report.
37
38.. _suppr_spec_label:
39
40Suppression specifications
41==========================
42
43
44Definition
45----------
46
47A suppression specification file is a way for a user to instruct
48:ref:`abidiff <abidiff_label>`, :ref:`abipkgdiff <abipkgdiff_label>`
49or any other relevant libabigail tool to avoid emitting reports for
50changes involving certain :ref:`ABI artifacts<abi_artifacts_label>`.
51
52It contains directives (or specifications) that describe the set of
53ABI artifacts to avoid emitting change reports about.
54
55Introductory examples
56---------------------
57
58Its syntax is based on a simplified and customized form of `Ini File
59Syntax`_.  For instance, to specify that change reports on a type
60named FooPrivateType should be suppressed, one could write this
61suppression specification: ::
62
63   [suppress_type]
64     name = FooPrivateType
65
66If we want to ensure that only change reports about structures named
67FooPrivateType should be suppressed, we could write: ::
68
69   [suppress_type]
70     type_kind = struct
71     name = FooPrivateType
72
73But we could also want to suppress change reports avoid typedefs named
74FooPrivateType.  In that case we would write:  ::
75
76   [suppress_type]
77     type_kind = typedef
78     name = FooPrivateType
79
80Or, we could want to suppress change reports about all struct which
81names end with the string "PrivateType": ::
82
83   [suppress_type]
84     type_kind = struct
85     name_regexp = ^.*PrivateType
86
87Let's now look at the generic syntax of suppression specification
88files.
89
90Syntax
91------
92
93Properties
94^^^^^^^^^^
95
96More generally, the format of suppression lists is organized around
97the concept of `property`.  Every property has a name and a value,
98delimited by the ``=`` sign.  E.g: ::
99
100	 name = value
101
102Leading and trailing white spaces are ignored around property names
103and values.
104
105.. _suppr_regexp_label:
106
107Regular expressions
108^^^^^^^^^^^^^^^^^^^
109
110The value of some properties might be a regular expression.  In that
111case, they must comply with the syntax of `extended POSIX regular
112expressions
113<http://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002dextended-regular-expression-syntax.html#posix_002dextended-regular-expression-syntax>`_.
114Note that Libabigail uses the regular expression engine of the `GNU C
115Library`_.
116
117Escaping a character in a regular expression
118^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
119
120When trying to match a string that contains a ``*`` character, like in
121the pointer type ``int*``, one must be careful to notice that the
122character ``*`` is a special character in the extended POSIX regular
123expression syntax.  And that character must be escaped for the regular
124expression engine.  Thus the regular expression that would match the
125string ``int*`` in a suppression file should be ::
126
127  int\\*
128
129Wait; but then why the two ``\`` characters?  Well, because the ``\``
130character is a special character in the `Ini File Syntax`_ used for
131specifying suppressions.  So it must be escaped as well, so that the
132Ini File parser leaves a ``\`` character intact in the data stream
133that is handed to the regular expression engine.  Hence the ``\\``
134targeted at the Ini File parser.
135
136So, in short, to escape a character in a regular expression, always
137prefix the character with the ``\\`` sequence.
138
139Modus operandi
140^^^^^^^^^^^^^^
141
142
143Suppression specifications can be applied at two different points of
144the processing pipeline of libabigail.
145
146.. _late_suppression_mode_label:
147
148In the default operating mode called "late suppression mode",
149suppression specifications are applied to the result of comparing the
150in-memory internal representations of two ABIs.  In this mode, if an
151ABI artifact matches a suppression specification, its changes are not
152mentioned in the ABI change report.  The internal representation of
153the "suppressed" changed ABI artifact is still present in memory; it
154is just not mentioned in the ABI change report.  The change report can
155still mention statistics about the number of changed ABI artifacts
156that were suppressed.
157
158.. _early_suppression_mode_label:
159
160There is another operating mode called the "early suppression mode"
161where suppression specifications are applied during the construction
162of the in-memory internal representation of a given ABI.  In that
163mode, if an ABI artifact matches a suppression specification, no
164in-memory internal representation is built for it.  As a result, no
165change about the matched ABI artifact is going to be mentioned in the
166ABI change report and no statistic about the number of suppressed ABI
167changes is available.  Also, please note that because suppressed ABI
168artifacts are removed from the in-memory internal representation in
169this mode, the amount memory used by the internal representation is
170potentially smaller than the memory consumption in the late
171suppression mode.
172
173Sections
174^^^^^^^^
175
176Properties are then grouped into arbitrarily named sections that shall
177not be nested.  The name of the section is on a line by itself and is
178surrounded by square brackets, i.e: ::
179
180	 [section_name]
181	 property1_name = property1_value
182	 property2_name = property2_value
183
184
185A section might or might not have properties.  Sections that expect to
186have properties and which are found nonetheless empty are just
187ignored.  Properties that are not recognized by the reader are ignored
188as well.
189
190Section names
191^^^^^^^^^^^^^
192
193Each different section can be thought of as being a directive to
194suppress ABI change reports for a particular kind of ABI artifact.
195
196``[suppress_file]``
197$$$$$$$$$$$$$$$$$$$
198
199This directive prevents a given tool from loading a file (binary or
200abixml file) if its file name or other properties match certain
201properties.  Thus, if the tool is meant to compare the ABIs of two
202files, and if the directive prevents it from loading either one of the
203files, then no comparison is performed.
204
205Note that for the ``[suppress_file]`` directive to work, at least one
206of the following properties must be provided:
207
208    ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``,
209    ``soname_not_regexp``.
210
211If none of the above properties are provided, then the
212``[suppress_file]`` directive is simply ignored.
213
214The potential properties of this sections are listed below:
215
216* ``file_name_not_regexp``
217
218  Usage:
219
220    ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
221
222  Prevents the system from loading the file which name does not match
223  the regular expression specified as value of this property.
224
225
226
227* ``file_name_regexp``
228
229  Usage:
230
231    ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
232
233  Prevents the system from loading the file which name matches the
234  regular expression specified as value of this property.
235
236
237* ``label``
238
239 Usage:
240
241   ``label`` ``=`` <some-value>
242
243 Define a label for the section.  A label is just an informative
244 string that might be used by the tool to refer to a type suppression
245 in error messages.
246
247
248* ``soname_regexp``
249
250  Usage:
251
252    ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
253
254  Prevents the system from loading the file which contains a SONAME
255  property that matches the regular expression of this property.  Note
256  that this property also works on an abixml file if it contains a
257  SONAME property.
258
259* ``soname_not_regexp``
260
261  Usage:
262
263    ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
264
265  Prevents the system from loading the file which contains a SONAME
266  property that does *NOT* match the regular expression of this
267  property.  Note that this property also works on an abixml file if
268  it contains a SONAME property.
269
270``[suppress_type]``
271$$$$$$$$$$$$$$$$$$$
272
273This directive suppresses report messages about a type change.
274
275Note that for the ``[suppress_type]`` directive to work, at least one
276of the following properties must be provided:
277
278  ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``,
279  ``soname_not_regexp``, ``name``, ``name_regexp``,
280  ``name_not_regexp``, ``source_location_not_in``,
281  ``source_location_not_regexp``, ``type_kind``.
282
283If none of the above properties are provided, then the
284``[suppress_type]`` directive is simply ignored.
285
286The potential properties of this sections are listed below:
287
288
289 .. _suppr_accessed_through_property_label:
290
291* ``accessed_through``
292
293 Usage:
294
295   ``accessed_through`` ``=`` <some-predefined-values>
296
297 Suppress change reports involving a type which is referred to either
298 directly or through a pointer or a reference.  The potential values
299 of this property are the predefined keywords below:
300
301	 * ``direct``
302
303	   So if the ``[suppress_type]`` contains the property
304	   description: ::
305
306	     accessed_through = direct
307
308	   then changes about a type that is referred-to
309	   directly (i.e, not through a pointer or a reference)
310	   are going to be suppressed.
311
312	 * ``pointer``
313
314	   If the ``accessed_through`` property is set to the
315	   value ``pointer`` then changes about a type that is
316	   referred-to through a pointer are going to be
317	   suppressed.
318
319	 * ``reference``
320
321	   If the ``accessed_through`` property is set to the
322	   value ``reference`` then changes about a type that is
323	   referred-to through a reference are going to be
324	   suppressed.
325
326	 * ``reference-or-pointer``
327
328	   If the ``accessed_through`` property is set to the
329	   value ``reference-or-pointer`` then changes about a
330	   type that is referred-to through either a reference
331	   or a pointer are going to be suppressed.
332
333 For an extensive example of how to use this property, please check
334 out the example below about :ref:`suppressing change reports about
335 types accessed either directly or through pointers
336 <example_accessed_through_label>`.
337
338
339.. _suppr_changed_enumerators_label:
340
341* ``changed_enumerators``
342
343  Usage:
344
345    ``changed_enumerators`` ``=`` <list-of-enumerators>
346
347  Suppresses change reports involving changes in the value of
348  enumerators of a given enum type.  This property is applied if the
349  ``type_kind`` property is set to the value ``enum``, at least.  The
350  value of the ``changed_enumerators`` is a comma-separated list of
351  the enumerators that the user expects to change.  For instance: ::
352
353      changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1
354
355
356.. _suppr_changed_enumerators_regexp_label:
357
358* ``changed_enumerators_regexp``
359
360  Usage:
361
362    ``changed_enumerators_regexp`` ``=`` <list-of-enumerator-regular-expressions>
363
364  Suppresses change reports involving changes in the value of
365  enumerators of a given enum type.  This property is applied if the
366  ``type_kind`` property is set to the value ``enum``, at least.  The
367  value of the ``changed_enumerators_regexp`` property is a
368  comma-separated list of regular expressions that should match the
369  names of the enumerators that the user expects to change.  For
370  instance: ::
371
372      changed_enumerators_regexp = .*_MAX$, .*_LAST$, .*_NUM$, .*_NBITS$
373
374  In the example above, change reports to any enumerator which name
375  ends with _MAX, _LAST, _NUM or _NBITS will be suppressed.
376
377  Note that for this property to be applied to changes to an enum
378  type, the size of the enum type must *NOT* have changed.
379
380
381* ``drop``
382
383 Usage:
384
385   ``drop`` ``=`` yes | no
386
387 If a type is matched by a suppression specification which contains
388 the "drop" property set to "yes" (or to "true") then the type is not
389 even going to be represented in the internal representation of the
390 ABI being analyzed.  This property makes its enclosing suppression
391 specification to be applied in the :ref:`early suppression
392 specification mode <early_suppression_mode_label>`.  The net effect
393 is that it potentially reduces the memory used to represent the ABI
394 being analyzed.
395
396 Please note that for this property to be effective, the enclosing
397 suppression specification must have at least one of the following
398 properties specified: ``name_regexp``, ``name``, ``name_regexp``,
399 ``source_location_not_in`` or ``source_location_not_regexp``.
400
401
402* ``file_name_not_regexp``
403
404  Usage:
405
406    ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
407
408  Suppresses change reports about ABI artifacts that are defined in a
409  binary file which name does not match the regular expression
410  specified as value of this property.
411
412
413* ``file_name_regexp``
414
415  Usage:
416
417    ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
418
419  Suppresses change reports about ABI artifacts that are defined in a
420  binary file which name matches the regular expression specified as
421  value of this property.
422
423
424 .. _suppr_has_data_member_label:
425
426* ``has_data_member``
427
428  Usage:
429
430    ``has_data_member`` ``=`` <``list-of-data-member-names``>
431
432Suppresses change reports involving a type which contains data members
433whose names are provided in the list value of this property.
434
435A usage examples of this property would be: ::
436
437  has_data_member = {private_data_member0, private_data_member1}
438
439
440The property above would match any type which contains at least two
441data members whose names are ``private_data_member0`` and
442``private_data_member1``.
443
444Another usage examples of this property would be: ::
445
446  has_data_member = another_private_data_member
447
448The property above would match any type which contains
449a data member which name is ``another_private_data_member0``.
450
451 .. _suppr_has_data_member_regexp_label:
452
453* ``has_data_member_regexp``
454
455  Usage:
456
457    ``has_data_member_regexp`` ``=`` <``a-regular-expression``>
458
459Suppresses change reports involving a type which contains data members
460whose names match the regular expression provided as the value of this
461property.
462
463A usage examples of this property would be: ::
464
465  has_data_member_regexp = ^private_data_member
466
467The property above would match any type which contains data members
468whose names match the regular expression ``^private_data_member``.  In
469other words, it would match any type which contains data members whose
470names start with the string "private_data_member".
471
472
473 .. _suppr_has_data_member_inserted_at_label:
474
475* ``has_data_member_inserted_at``
476
477 Usage:
478
479   ``has_data_member_inserted_at`` ``=`` <``offset-in-bit``>
480
481 Suppresses change reports involving a type which has at least one
482 data member inserted at an offset specified by the property value
483 ``offset-in-bit``.  Please note that if the size of the type changed,
484 then the type change will *NOT* be suppressed by the evaluation of
485 this property, unless the
486 :ref:`has_size_change<suppr_has_size_change_property_label>` property
487 is present and set to ``yes``.
488
489 The value ``offset-in-bit`` is either:
490
491	 - an integer value, expressed in bits, which denotes the
492	   offset of the insertion point of the data member, starting
493	   from the beginning of the relevant structure or class.
494
495.. _suppr_data_member_offset_selector_expressions_label:
496
497	 - data member offset selector expressions, such as:
498
499	     - the keyword ``end`` which is a named constant which
500	       value equals the offset of the end of the structure or
501	       class.
502
503	     - the keyword ``offset_of_flexible_array_data_member``
504               which is a named constant that evaluates to the offset
505               of the flexible array data member contained in the
506               relevant structure.
507
508	     - the function call expression
509	       ``offset_of(data-member-name)`` where `data-member-name` is
510	       the name of a given data member of the relevant structure
511	       or class.  The value of this function call expression is an
512	       integer that represents the offset of the data member
513	       denoted by ``data-member-name``.
514
515	     - the function call expression
516	       ``offset_after(data-member-name)`` where `data-member-name`
517	       is the name of a given data member of the relevant
518	       structure or class.  The value of this function call
519	       expression is an integer that represents the offset of the
520	       point that comes right after the region occupied by the
521	       data member denoted by ``data-member-name``.
522
523	     - the function call expression
524	       ``offset_of_first_data_member_regexp(data-member-name-regexp)``
525	       where `data-member-name-regexp` is a regular expression
526	       matching a data member.  The value of this function
527	       call expression is an integer that represents the
528	       offset of the first data member which name matches the
529	       regular expression argument.  If no data member of a
530	       given class type matches the regular expression, then
531	       the class type won't match the current directive.
532
533	     - the function call expression
534	       ``offset_of_last_data_member_regexp(data-member-name-regexp)``
535	       where `data-member-name-regexp` is a regular expression
536	       matching a data member.  The value of this function
537	       call expression is an integer that represents the
538	       offset of the last data member which name matches the
539	       regular expression argument.  If no data member of a
540	       given class type matches the regular expression, then
541	       the class type won't match the current directive.
542
543  .. _suppr_has_data_member_inserted_between_label:
544
545
546* ``has_data_member_inserted_between``
547
548 Usage:
549
550   ``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>}
551
552 Suppresses change reports involving a type which has at least one
553 data member inserted at an offset that is comprised in the range
554 between ``range-begin`` and ``range-end``.  Please note that each of
555 the values ``range-begin`` and ``range-end`` can be of the same form
556 as the :ref:`has_data_member_inserted_at
557 <suppr_has_data_member_inserted_at_label>` property above.  Please
558 also note that if the size of the type changed, then the type change
559 will *NOT* be suppressed by the evaluation of this property, unless
560 the :ref:`has_size_change<suppr_has_size_change_property_label>`
561 property is present and set to ``yes``.  Note that data member
562 deletions happening in the range between ``range-begin`` and
563 ``range-end`` won't prevent the type change from being suppressed by
564 the evaluation of this property if the size of the type doesn't
565 change or if the
566 :ref:`has_size_change<suppr_has_size_change_property_label>` property
567 is present and set to ``yes``.
568
569 Usage examples of this properties are: ::
570
571   has_data_member_inserted_between = {8, 64}
572
573 or: ::
574
575   has_data_member_inserted_between = {16, end}
576
577 or: ::
578
579   has_data_member_inserted_between = {offset_after(member1), end}
580
581.. _suppr_has_data_members_inserted_between_label:
582
583
584* ``has_data_members_inserted_between``
585
586 Usage:
587
588   ``has_data_members_inserted_between`` ``=`` {<sequence-of-ranges>}
589
590 Suppresses change reports involving a type which has multiple data
591 member inserted in various offset ranges.  A usage example of this
592 property is, for instance: ::
593
594   has_data_members_inserted_between = {{8, 31}, {72, 95}}
595
596 This usage example suppresses change reports involving a type which
597 has data members inserted in bit offset ranges [8 31] and [72 95].
598 The length of the sequence of ranges or this
599 ``has_data_members_inserted_between`` is not bounded; it can be as
600 long as the system can cope with.  The values of the boundaries of
601 the ranges are of the same kind as for the
602 :ref:`has_data_member_inserted_at
603 <suppr_has_data_member_inserted_at_label>` property above.  Please
604 also note that if the size of the type changed, then the type will
605 *NOT* be suppressed by the evaluation of this property, unless the
606 :ref:`has_size_change<suppr_has_size_change_property_label>` property
607 is present and set to ``yes``.  Note that data member deletions
608 happening in the defined ranges won't prevent the type change from
609 being suppressed by the evaluation of this property if the size of
610 the type doesn't change or if the
611 :ref:`has_size_change<suppr_has_size_change_property_label>` property
612 is present and set to ``yes``.
613
614 Another usage example of this property is thus: ::
615
616   has_data_members_inserted_between =
617     {
618	  {offset_after(member0), offset_of(member1)},
619	  {72, end}
620     }
621
622
623
624 .. _suppr_has_size_change_property_label:
625
626* ``has_size_change``
627
628 Usage:
629
630   ``has_size_change`` ``=`` yes | no
631
632
633This property is to be used in conjunction with the properties
634:ref:`has_data_member_inserted_between<suppr_has_data_member_inserted_between_label>`
635and
636:ref:`has_data_members_inserted_between<suppr_has_data_members_inserted_between_label>`.
637Those properties will not match a type change if the size of the type
638changes, unless the ``has_size_changes`` property is set to ``yes``.
639
640 .. _suppr_label_property_label:
641
642* ``label``
643
644 Usage:
645
646   ``label`` ``=`` <some-value>
647
648 Define a label for the section.  A label is just an informative
649 string that might be used by a tool to refer to a type suppression in
650 error messages.
651
652
653* ``name``
654
655 Usage:
656
657   ``name`` ``=`` <a-value>
658
659 Suppresses change reports involving types whose name equals the value
660 of this property.
661
662
663* ``name_not_regexp``
664
665 Usage:
666
667   ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
668
669 Suppresses change reports involving types whose name does *NOT* match
670 the regular expression specified as value of this property.  Said
671 otherwise, this property specifies which types to keep, rather than
672 types to suppress from reports.
673
674
675* ``name_regexp``
676
677 Usage:
678
679   ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
680
681 Suppresses change reports involving types whose name matches the
682 regular expression specified as value of this property.
683
684
685* ``soname_not_regexp``
686
687  Usage:
688
689    ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
690
691  Suppresses change reports about ABI artifacts that are defined in a
692  shared library which SONAME property does not match the regular
693  expression specified as value of this property.
694
695
696* ``soname_regexp``
697
698  Usage:
699
700    ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
701
702  Suppresses change reports about ABI artifacts that are defined in a
703  shared library which SONAME property matches the regular expression
704  specified as value of this property.
705
706 .. _suppr_source_location_not_in_label:
707
708* ``source_location_not_in``
709
710 Usage:
711
712    ``source_location_not_in`` ``=`` <``list-of-file-paths``>
713
714 Suppresses change reports involving a type which is defined in a file
715 which path is *NOT* listed in the value ``list-of-file-paths``.  Note
716 that the value is a comma-separated list of file paths e.g, this
717 property ::
718
719   source_location_not_in = libabigail/abg-ir.h, libabigail/abg-dwarf-reader.h
720
721 suppresses change reports about all the types that are *NOT* defined
722 in header files whose path end up with the strings
723 libabigail/abg-ir.h or libabigail/abg-dwarf-reader.h.
724
725 .. _suppr_source_location_not_regexp_label:
726
727
728* ``source_location_not_regexp``
729
730 Usage:
731
732   ``source_location_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
733
734 Suppresses change reports involving a type which is defined in a file
735 which path does *NOT* match the :ref:`regular expression
736 <suppr_regexp_label>` provided as value of the property. E.g, this
737 property ::
738
739   source_location_not_regexp = libabigail/abg-.*\\.h
740
741 suppresses change reports involving all the types that are *NOT*
742 defined in header files whose path match the regular expression
743 provided a value of the property.
744
745
746* ``type_kind``
747
748 Usage:
749
750   ``type_kind`` ``=`` ``class`` | ``struct`` | ``union`` | ``enum`` |
751		       ``array`` | ``typedef`` | ``builtin``
752
753 Suppresses change reports involving a certain kind of type.  The kind
754 of type to suppress change reports for is specified by the possible
755 values listed above:
756
757   - ``class``: suppress change reports for class types.  Note that
758	 even if class types don't exist for C, this value still
759	 triggers the suppression of change reports for struct types,
760	 in C.  In C++ however, it should do what it suggests.
761
762   - ``struct``: suppress change reports for struct types in C or C++.
763	 Note that the value ``class`` above is a super-set of this
764	 one.
765
766   - ``union``: suppress change reports for union types.
767
768   - ``enum``: suppress change reports for enum types.
769
770   - ``array``: suppress change reports for array types.
771
772   - ``typedef``: suppress change reports for typedef types.
773
774   - ``builtin``: suppress change reports for built-in (or native)
775     types.  Example of built-in types are char, int, unsigned int,
776     etc.
777
778
779``[suppress_function]``
780$$$$$$$$$$$$$$$$$$$$$$$$
781
782This directive suppresses report messages about changes on a set of
783functions.
784
785Note that for the ``[suppress_function]`` directive to work, at least
786one of the following properties must be provided:
787
788  ``label``, ``file_name_regexp``, ``file_name_not_regexp``,
789  ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``,
790  ``name_not_regexp``, ``parameter``, ``return_type_name``,
791  ``return_type_regexp``, ``symbol_name``, ``symbol_name_regexp``,
792  ``symbol_name_not_regexp``, ``symbol_version``,
793  ``symbol_version_regexp``.
794
795If none of the above properties are provided, then the
796``[suppress_function]`` directive is simply ignored.
797
798The potential properties of this sections are:
799
800
801  .. _suppr_change_kind_property_label:
802
803* ``change_kind``
804
805 Usage:
806
807   ``change_kind`` ``=`` <predefined-possible-values>
808
809 Specifies the kind of changes this suppression specification should
810 apply to.  The possible values of this property as well as their
811 meaning are listed below:
812
813	 - ``function-subtype-change``
814
815	   This suppression specification applies to functions
816	   that which have at least one sub-type that has
817	   changed.
818
819	 - ``added-function``
820
821	   This suppression specification applies to functions
822	   that have been added to the binary.
823
824	 - ``deleted-function``
825
826	   This suppression specification applies to functions
827	   that have been removed from the binary.
828
829	 - ``all``
830
831	   This suppression specification applies to functions
832	   that have all of the changes above.  Note that not
833	   providing the ``change_kind`` property at all is
834	   equivalent to setting it to the value ``all``.
835
836
837* ``drop``
838
839 Usage:
840
841   ``drop`` ``=`` yes | no
842
843 If a function is matched by a suppression specification which
844 contains the "drop" property set to "yes" (or to "true") then the
845 function is not even going to be represented in the internal
846 representation of the ABI being analyzed.  This property makes its
847 enclosing suppression specification to be applied in the :ref:`early
848 suppression specification mode <early_suppression_mode_label>`.  The
849 net effect is that it potentially reduces the memory used to
850 represent the ABI being analyzed.
851
852 Please note that for this property to be effective, the enclosing
853 suppression specification must have at least one of the following
854 properties specified: ``name_regexp``, ``name``, ``name_regexp``,
855 ``source_location_not_in`` or ``source_location_not_regexp``.
856
857
858* ``file_name_not_regexp``
859
860  Usage:
861
862    ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
863
864  Suppresses change reports about ABI artifacts that are defined in a
865  binary file which name does not match the regular expression
866  specified as value of this property.
867
868
869* ``file_name_regexp``
870
871  Usage:
872
873  ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
874
875  Suppresses change reports about ABI artifacts that are defined in a
876  binary file which name matches the regular expression specified as
877  value of this property.
878
879
880* ``label``
881
882 Usage:
883
884   ``label`` ``=`` <some-value>
885
886 This property is the same as the :ref:`label property
887 <suppr_label_property_label>` defined above.
888
889
890* ``name``
891
892 Usage:
893
894   ``name`` ``=`` <some-value>
895
896 Suppresses change reports involving functions whose name equals the
897 value of this property.
898
899
900* ``name_not_regexp``
901
902 Usage:
903
904   ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
905
906 Suppresses change reports involving functions whose names don't match
907 the regular expression specified as value of this property.
908
909 The rules for functions that have several symbol names are the same
910 rules as for the ``name_regexp`` property above.
911
912
913* ``name_regexp``
914
915 Usage:
916
917   ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
918
919 Suppresses change reports involving functions whose name matches the
920 regular expression specified as value of this property.
921
922 Let's consider the case of functions that have several symbol names.
923 This happens when the underlying symbol for the function has
924 aliases.  Each symbol name is actually one alias name.
925
926 In this case, if the regular expression matches the name of
927 at least one of the aliases names, then it must match the names of
928 all of the aliases of the function for the directive to actually
929 suppress the diff reports for said function.
930
931
932* ``parameter``
933
934 Usage:
935
936   ``parameter`` ``=`` <function-parameter-specification>
937
938 Suppresses change reports involving functions whose
939 parameters match the parameter specification indicated as
940 value of this property.
941
942 The format of the function parameter specification is:
943
944 ``'`` ``<parameter-index>`` ``<space>`` ``<type-name-or-regular-expression>``
945
946 That is, an apostrophe followed by a number that is the
947 index of the parameter, followed by one of several spaces,
948 followed by either the name of the type of the parameter,
949 or a regular expression describing a family of parameter
950 type names.
951
952 If the parameter type name is designated by a regular
953 expression, then said regular expression must be enclosed
954 between two slashes; like ``/some-regular-expression/``.
955
956 The index of the first parameter of the function is zero.
957 Note that for member functions (methods of classes), the
958 this is the first parameter that comes after the implicit
959 "this" pointer parameter.
960
961 Examples of function parameter specifications are: ::
962
963   '0 int
964
965 Which means, the parameter at index 0, whose type name is
966 ``int``. ::
967
968   '4 unsigned char*
969
970 Which means, the parameter at index 4, whose type name is
971 ``unsigned char*``.  ::
972
973   '2 /^foo.*&/
974
975 Which means, the parameter at index 2, whose type name
976 starts with the string "foo" and ends with an '&'.  In
977 other words, this is the third parameter and it's a
978 reference on a type that starts with the string "foo".
979
980
981* ``return_type_name``
982
983 Usage:
984
985   ``return_type_name`` ``=`` <some-value>
986
987 Suppresses change reports involving functions whose return type name
988 equals the value of this property.
989
990
991* ``return_type_regexp``
992
993 Usage:
994
995   ``return_type_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
996
997 Suppresses change reports involving functions whose return type name
998 matches the regular expression specified as value of this property.
999
1000
1001* ``soname_regexp``
1002
1003  Usage:
1004
1005    ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1006
1007  Suppresses change reports about ABI artifacts that are defined in a
1008  shared library which SONAME property matches the regular expression
1009  specified as value of this property.
1010
1011
1012* ``soname_not_regexp``
1013
1014  Usage:
1015
1016    ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1017
1018  Suppresses change reports about ABI artifacts that are defined in a
1019  shared library which SONAME property does not match the regular
1020  expression specified as value of this property.
1021
1022
1023* ``symbol_name``
1024
1025 Usage:
1026
1027   ``symbol_name`` ``=`` <some-value>
1028
1029 Suppresses change reports involving functions whose symbol name equals
1030 the value of this property.
1031
1032
1033* ``symbol_name_regexp``
1034
1035 Usage:
1036
1037   ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1038
1039 Suppresses change reports involving functions whose symbol name
1040 matches the regular expression specified as value of this property.
1041
1042 Let's consider the case of functions that have several symbol names.
1043 This happens when the underlying symbol for the function has
1044 aliases.  Each symbol name is actually one alias name.
1045
1046 In this case, the regular expression must match the names of all of
1047 the aliases of the function for the directive to actually suppress
1048 the diff reports for said function.
1049
1050
1051* ``symbol_name_not_regexp``
1052
1053 Usage:
1054
1055   ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1056
1057 Suppresses change reports involving functions whose symbol name does
1058 not match the regular expression specified as value of this property.
1059
1060
1061* ``symbol_version``
1062
1063 Usage:
1064
1065   ``symbol_version`` ``=`` <some-value>
1066
1067 Suppresses change reports involving functions whose symbol version
1068 equals the value of this property.
1069
1070
1071* ``symbol_version_regexp``
1072
1073 Usage:
1074
1075   ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1076
1077 Suppresses change reports involving functions whose symbol version
1078 matches the regular expression specified as value of this property.
1079
1080
1081``[suppress_variable]``
1082$$$$$$$$$$$$$$$$$$$$$$$$
1083
1084This directive suppresses report messages about changes on a set of
1085variables.
1086
1087Note that for the ``[suppress_variable]`` directive to work, at least
1088one of the following properties must be provided:
1089
1090  ``label``, ``file_name_regexp``, ``file_name_not_regexp``,
1091  ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``,
1092  ``name_not_regexp``, ``symbol_name``, ``symbol_name_regexp``,
1093  ``symbol_name_not_regexp``, ``symbol_version``,
1094  ``symbol_version_regexp``, ``type_name``, ``type_name_regexp``.
1095
1096If none of the above properties are provided, then the
1097``[suppress_variable]`` directive is simply ignored.
1098
1099The potential properties of this sections are:
1100
1101* ``label``
1102
1103 Usage:
1104
1105   ``label`` ``=`` <some-value>
1106
1107 This property is the same as the :ref:`label property
1108 <suppr_label_property_label>` defined above.
1109
1110
1111* ``file_name_regexp``
1112
1113  Usage:
1114
1115  ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1116
1117  Suppresses change reports about ABI artifacts that are defined in a
1118  binary file which name matches the regular expression specified as
1119  value of this property.
1120
1121* ``file_name_not_regexp``
1122
1123  Usage:
1124
1125   ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1126
1127  Suppresses change reports about ABI artifacts that are defined in a
1128  binary file which name does not match the regular expression
1129  specified as value of this property.
1130
1131
1132* ``soname_regexp``
1133
1134  Usage:
1135
1136   ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1137
1138  Suppresses change reports about ABI artifacts that are defined in a
1139  shared library which SONAME property matches the regular expression
1140  specified as value of this property.
1141
1142
1143* ``soname_not_regexp``
1144
1145  Usage:
1146
1147    ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1148
1149  Suppresses change reports about ABI artifacts that are defined in a
1150  shared library which SONAME property does not match the regular
1151  expression specified as value of this property.
1152
1153
1154* ``name``
1155
1156 Usage:
1157
1158   ``name`` ``=`` <some-value>
1159
1160 Suppresses change reports involving variables whose name equals the
1161 value of this property.
1162
1163* ``name_regexp``
1164
1165 Usage:
1166
1167   ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1168
1169 Suppresses change reports involving variables whose name matches the
1170 regular expression specified as value of this property.
1171
1172* ``change_kind``
1173
1174 Usage:
1175
1176   ``change_kind`` ``=`` <predefined-possible-values>
1177
1178 Specifies the kind of changes this suppression specification should
1179 apply to.  The possible values of this property as well as their
1180 meaning are the same as when it's :ref:`used in the
1181 [suppress_function] section <suppr_change_kind_property_label>`.
1182
1183* ``symbol_name``
1184
1185 Usage:
1186
1187   ``symbol_name`` ``=`` <some-value>
1188
1189 Suppresses change reports involving variables whose symbol name equals
1190 the value of this property.
1191
1192* symbol_name_regexp
1193
1194 Usage:
1195
1196   ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1197
1198 Suppresses change reports involving variables whose symbol name
1199 matches the regular expression specified as value of this property.
1200
1201
1202* ``symbol_name_not_regexp``
1203
1204 Usage:
1205
1206   ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1207
1208 Suppresses change reports involving variables whose symbol name does
1209 not match the regular expression specified as value of this property.
1210
1211* ``symbol_version``
1212
1213 Usage:
1214
1215   ``symbol_version`` ``=`` <some-value>
1216
1217 Suppresses change reports involving variables whose symbol version
1218 equals the value of this property.
1219
1220* ``symbol_version_regexp``
1221
1222 Usage:
1223
1224   ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1225
1226 Suppresses change reports involving variables whose symbol version
1227 matches the regular expression specified as value of this property.
1228
1229* ``type_name``
1230
1231 Usage:
1232
1233   ``type_name`` ``=`` <some-value>
1234
1235 Suppresses change reports involving variables whose type name equals
1236 the value of this property.
1237
1238* ``type_name_regexp``
1239
1240 Usage:
1241
1242   ``type_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1243
1244 Suppresses change reports involving variables whose type name matches
1245 the regular expression specified as value of this property.
1246
1247Comments
1248^^^^^^^^
1249
1250``;`` or ``#`` ASCII character at the beginning of a line
1251indicates a comment.  Comment lines are ignored.
1252
1253Code examples
1254^^^^^^^^^^^^^
1255
12561. Suppressing change reports about types.
1257
1258   Suppose we have a library named ``libtest1-v0.so`` which
1259   contains this very useful code: ::
1260
1261	$ cat -n test1-v0.cc
1262	     1	// A forward declaration for a type considered to be opaque to
1263	     2	// function foo() below.
1264	     3	struct opaque_type;
1265	     4
1266	     5	// This function cannot touch any member of opaque_type.  Hence,
1267	     6	// changes to members of opaque_type should not impact foo, as far as
1268	     7	// ABI is concerned.
1269	     8	void
1270	     9	foo(opaque_type*)
1271	    10	{
1272	    11	}
1273	    12
1274	    13	struct opaque_type
1275	    14	{
1276	    15	  int member0;
1277	    16	  char member1;
1278	    17	};
1279	$
1280
1281Let's change the layout of struct opaque_type by inserting a data
1282member around line 15, leading to a new version of the library,
1283that we shall name ``libtest1-v1.so``: ::
1284
1285	$ cat -n test1-v1.cc
1286	     1	// A forward declaration for a type considered to be opaque to
1287	     2	// function foo() below.
1288	     3	struct opaque_type;
1289	     4
1290	     5	// This function cannot touch any member of opaque_type;  Hence,
1291	     6	// changes to members of opaque_type should not impact foo, as far as
1292	     7	// ABI is concerned.
1293	     8	void
1294	     9	foo(opaque_type*)
1295	    10	{
1296	    11	}
1297	    12
1298	    13	struct opaque_type
1299	    14	{
1300	    15	  char added_member; // <-- a new member got added here now.
1301	    16	  int member0;
1302	    17	  char member1;
1303	    18	};
1304	$
1305
1306Let's compile both examples.  We shall not forget to compile them
1307with debug information generation turned on: ::
1308
1309	$ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc
1310	$ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc
1311
1312Let's ask :ref:`abidiff <abidiff_label>` which ABI differences it sees
1313between ``libtest1-v0.so`` and ``libtest1-v1.so``: ::
1314
1315	$ abidiff libtest1-v0.so libtest1-v1.so
1316	Functions changes summary: 0 Removed, 1 Changed, 0 Added function
1317	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1318
1319	1 function with some indirect sub-type change:
1320
1321	  [C]'function void foo(opaque_type*)' has some indirect sub-type changes:
1322	    parameter 0 of type 'opaque_type*' has sub-type changes:
1323	      in pointed to type 'struct opaque_type':
1324		size changed from 64 to 96 bits
1325		1 data member insertion:
1326		  'char opaque_type::added_member', at offset 0 (in bits)
1327		2 data member changes:
1328		 'int opaque_type::member0' offset changed from 0 to 32
1329		 'char opaque_type::member1' offset changed from 32 to 64
1330
1331
1332So ``abidiff`` reports that the opaque_type's layout has changed
1333in a significant way, as far as ABI implications are concerned, in
1334theory.  After all, a sub-type (``struct opaque_type``) of an
1335exported function (``foo()``) has seen its layout change.  This
1336might have non negligible ABI implications.  But in practice here,
1337the programmer of the litest1-v1.so library knows that the "soft"
1338contract between the function ``foo()`` and the type ``struct
1339opaque_type`` is to stay away from the data members of the type.
1340So layout changes of ``struct opaque_type`` should not impact
1341``foo()``.
1342
1343Now to teach ``abidiff`` about this soft contract and have it
1344avoid emitting what amounts to false positives in this case, we
1345write the suppression specification file below: ::
1346
1347	$ cat test1.suppr
1348	[suppress_type]
1349	  type_kind = struct
1350	  name = opaque_type
1351
1352Translated in plain English, this suppression specification would
1353read: "Do not emit change reports about a struct which name is
1354opaque_type".
1355
1356Let's now invoke ``abidiff`` on the two versions of the library
1357again, but this time with the suppression specification: ::
1358
1359	$ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so
1360	Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
1361	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1362
1363As you can see, ``abidiff`` does not report the change anymore; it
1364tells us that it was filtered out instead.
1365
1366Suppressing change reports about types with data member
1367insertions
1368
1369Suppose the first version of a library named ``libtest3-v0.so``
1370has this source code: ::
1371
1372	/* Compile this with:
1373	     gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c
1374	 */
1375
1376	struct S
1377	{
1378	  char member0;
1379	  int member1; /*
1380			  between member1 and member2, there is some padding,
1381			  at least on some popular platforms.  On
1382			  these platforms, adding a small enough data
1383			  member into that padding shouldn't change
1384			  the offset of member1.  Right?
1385			*/
1386	};
1387
1388	int
1389	foo(struct S* s)
1390	{
1391	  return s->member0 + s->member1;
1392	}
1393
1394Now, suppose the second version of the library named
1395``libtest3-v1.so`` has this source code in which a data member
1396has been added in the padding space of struct S and another data
1397member has been added at its end: ::
1398
1399	/* Compile this with:
1400	     gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c
1401	 */
1402
1403	struct S
1404	{
1405	  char member0;
1406	  char inserted1; /* <---- A data member has been added here...  */
1407	  int member1;
1408	  char inserted2; /* <---- ... and another one has been added here.  */
1409	};
1410
1411	int
1412	foo(struct S* s)
1413	{
1414	  return s->member0 + s->member1;
1415	}
1416
1417
1418In libtest3-v1.so, adding char data members ``S::inserted1`` and
1419``S::inserted2`` can be considered harmless (from an ABI compatibility
1420perspective), at least on the x86 platform, because that doesn't
1421change the offsets of the data members S::member0 and S::member1.  But
1422then running ``abidiff`` on these two versions of library yields: ::
1423
1424	$ abidiff libtest3-v0.so libtest3-v1.so
1425	Functions changes summary: 0 Removed, 1 Changed, 0 Added function
1426	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1427
1428	1 function with some indirect sub-type change:
1429
1430	  [C]'function int foo(S*)' has some indirect sub-type changes:
1431	    parameter 0 of type 'S*' has sub-type changes:
1432	      in pointed to type 'struct S':
1433		type size changed from 64 to 96 bits
1434		2 data member insertions:
1435		  'char S::inserted1', at offset 8 (in bits)
1436		  'char S::inserted2', at offset 64 (in bits)
1437	$
1438
1439
1440
1441That is, ``abidiff`` shows us the two changes, even though we (the
1442developers of that very involved library) know that these changes
1443are harmless in this particular context.
1444
1445Luckily, we can devise a suppression specification that essentially
1446tells abidiff to filter out change reports about adding a data
1447member between ``S::member0`` and ``S::member1``, and adding a data
1448member at the end of struct S.  We have written such a suppression
1449specification in a file called test3-1.suppr and it unsurprisingly
1450looks like: ::
1451
1452	[suppress_type]
1453	  name = S
1454	  has_data_member_inserted_between = {offset_after(member0), offset_of(member1)}
1455	  has_data_member_inserted_at = end
1456
1457
1458Now running ``abidiff`` with this suppression specification yields: ::
1459
1460	$ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so
1461	Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
1462	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1463
1464	$
1465
1466
1467Hooora! \\o/ (I guess)
1468
1469.. _example_accessed_through_label:
1470
1471Suppressing change reports about types accessed either directly
1472or through pointers
1473
1474Suppose we have a first version of an object file which source
1475code is the file widget-v0.cc below: ::
1476
1477	// Compile with: g++ -g -c widget-v0.cc
1478
1479	struct widget
1480	{
1481	  int x;
1482	  int y;
1483
1484	  widget()
1485	    :x(), y()
1486	  {}
1487	};
1488
1489	void
1490	fun0(widget*)
1491	{
1492	  // .. do stuff here.
1493	}
1494
1495	void
1496	fun1(widget&)
1497	{
1498	  // .. do stuff here ..
1499	}
1500
1501	void
1502	fun2(widget w)
1503	{
1504	  // ... do other stuff here ...
1505	}
1506
1507Now suppose in the second version of that file, named
1508widget-v1.cc, we have added some data members at the end of
1509the type ``struct widget``; here is what the content of that file
1510would look like: ::
1511
1512	// Compile with: g++ -g -c widget-v1.cc
1513
1514	struct widget
1515	{
1516	  int x;
1517	  int y;
1518	  int w; // We have added these two new data members here ..
1519	  int h; // ... and here.
1520
1521	  widget()
1522	    : x(), y(), w(), h()
1523	  {}
1524	};
1525
1526	void
1527	fun0(widget*)
1528	{
1529	  // .. do stuff here.
1530	}
1531
1532	void
1533	fun1(widget&)
1534	{
1535	  // .. do stuff here ..
1536	}
1537
1538	void
1539	fun2(widget w)
1540	{
1541	  // ... do other stuff here ...
1542	}
1543
1544When we invoke ``abidiff`` on the object files resulting from the
1545compilation of the two file above, here is what we get: ::
1546
1547	$ abidiff widget-v0.o widget-v1.o
1548	Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions
1549	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1550
1551	2 functions with some indirect sub-type change:
1552
1553	  [C]'function void fun0(widget*)' has some indirect sub-type changes:
1554	    parameter 1 of type 'widget*' has sub-type changes:
1555	      in pointed to type 'struct widget':
1556		type size changed from 64 to 128 bits
1557		2 data member insertions:
1558		  'int widget::w', at offset 64 (in bits)
1559		  'int widget::h', at offset 96 (in bits)
1560
1561	  [C]'function void fun2(widget)' has some indirect sub-type changes:
1562	    parameter 1 of type 'struct widget' has sub-type changes:
1563	      details were reported earlier
1564       $
1565
1566I guess a little bit of explaining is due here.  ``abidiff``
1567detects that two data member got added at the end of ``struct
1568widget``.  it also tells us that the type change impacts the
1569exported function ``fun0()`` which uses the type ``struct
1570widget`` through a pointer, in its signature.
1571
1572Careful readers will notice that the change to ``struct widget``
1573also impacts the exported function ``fun1()``, that uses type
1574``struct widget`` through a reference.  But then ``abidiff``
1575doesn't tell us about the impact on that function ``fun1()``
1576because it has evaluated that change as being **redundant** with
1577the change it reported on ``fun0()``.  It has thus filtered it
1578out, to avoid cluttering the output with noise.
1579
1580Redundancy detection and filtering is fine and helpful to avoid
1581burying the important information in a sea of noise.  However, it
1582must be treated with care, by fear of mistakenly filtering out
1583relevant and important information.
1584
1585That is why ``abidiff`` tells us about the impact that the change
1586to ``struct widget`` has on function ``fun2()``.  In this case,
1587that function uses the type ``struct widget`` **directly** (in
1588its signature).  It does not use it via a pointer or a reference.
1589In this case, the direct use of this type causes ``fun2()`` to be
1590exposed to a potentially harmful ABI change.  Hence, the report
1591about ``fun2()`` is not filtered out, even though it's about that
1592same change on ``struct widget``.
1593
1594To go further in suppressing reports about changes that are
1595harmless and keeping only those that we know are harmful, we
1596would like to go tell abidiff to suppress reports about this
1597particular ``struct widget`` change when it impacts uses of
1598``struct widget`` through a pointer or reference.  In other
1599words, suppress the change reports about ``fun0()`` **and**
1600``fun1()``.  We would then write this suppression specification,
1601in file ``widget.suppr``: ::
1602
1603	[suppress_type]
1604	  name = widget
1605	  type_kind = struct
1606	  has_data_member_inserted_at = end
1607	  accessed_through = reference-or-pointer
1608
1609	  # So this suppression specification says to suppress reports about
1610	  # the type 'struct widget', if this type was added some data member
1611	  # at its end, and if the change impacts uses of the type through a
1612	  # reference or a pointer.
1613
1614Invoking ``abidiff`` on ``widget-v0.o`` and ``widget-v1.o`` with
1615this suppression specification yields: ::
1616
1617	$ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o
1618	Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1619	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1620
1621	1 function with some indirect sub-type change:
1622
1623	  [C]'function void fun2(widget)' has some indirect sub-type changes:
1624	    parameter 1 of type 'struct widget' has sub-type changes:
1625	      type size changed from 64 to 128 bits
1626	      2 data member insertions:
1627		'int widget::w', at offset 64 (in bits)
1628		'int widget::h', at offset 96 (in bits)
1629	$
1630
1631As expected, I guess.
1632
1633Suppressing change reports about functions.
1634
1635Suppose we have a first version a library named
1636``libtest2-v0.so`` whose source code is: ::
1637
1638	 $ cat -n test2-v0.cc
1639
1640	  1	struct S1
1641	  2	{
1642	  3	  int m0;
1643	  4
1644	  5	  S1()
1645	  6	    : m0()
1646	  7	  {}
1647	  8	};
1648	  9
1649	 10	struct S2
1650	 11	{
1651	 12	  int m0;
1652	 13
1653	 14	  S2()
1654	 15	    : m0()
1655	 16	  {}
1656	 17	};
1657	 18
1658	 19	struct S3
1659	 20	{
1660	 21	  int m0;
1661	 22
1662	 23	  S3()
1663	 24	    : m0()
1664	 25	  {}
1665	 26	};
1666	 27
1667	 28	int
1668	 29	func(S1&)
1669	 30	{
1670	 31	  // suppose the code does something with the argument.
1671	 32	  return 0;
1672	 33
1673	 34	}
1674	 35
1675	 36	char
1676	 37	func(S2*)
1677	 38	{
1678	 39	  // suppose the code does something with the argument.
1679	 40	  return 0;
1680	 41	}
1681	 42
1682	 43	unsigned
1683	 44	func(S3)
1684	 45	{
1685	 46	  // suppose the code does something with the argument.
1686	 47	  return 0;
1687	 48	}
1688	$
1689
1690And then we come up with a second version ``libtest2-v1.so`` of
1691that library; the source code is modified by making the
1692structures ``S1``, ``S2``, ``S3`` inherit another struct: ::
1693
1694	$ cat -n test2-v1.cc
1695	      1	struct base_type
1696	      2	{
1697	      3	  int m_inserted;
1698	      4	};
1699	      5
1700	      6	struct S1 : public base_type // <--- S1 now has base_type as its base
1701	      7				     // type.
1702	      8	{
1703	      9	  int m0;
1704	     10
1705	     11	  S1()
1706	     12	    : m0()
1707	     13	  {}
1708	     14	};
1709	     15
1710	     16	struct S2 : public base_type // <--- S2 now has base_type as its base
1711	     17				     // type.
1712	     18	{
1713	     19	  int m0;
1714	     20
1715	     21	  S2()
1716	     22	    : m0()
1717	     23	  {}
1718	     24	};
1719	     25
1720	     26	struct S3 : public base_type // <--- S3 now has base_type as its base
1721	     27				     // type.
1722	     28	{
1723	     29	  int m0;
1724	     30
1725	     31	  S3()
1726	     32	    : m0()
1727	     33	  {}
1728	     34	};
1729	     35
1730	     36	int
1731	     37	func(S1&)
1732	     38	{
1733	     39	  // suppose the code does something with the argument.
1734	     40	  return 0;
1735	     41
1736	     42	}
1737	     43
1738	     44	char
1739	     45	func(S2*)
1740	     46	{
1741	     47	  // suppose the code does something with the argument.
1742	     48	  return 0;
1743	     49	}
1744	     50
1745	     51	unsigned
1746	     52	func(S3)
1747	     53	{
1748	     54	  // suppose the code does something with the argument.
1749	     55	  return 0;
1750	     56	}
1751	 $
1752
1753Now let's build the two libraries: ::
1754
1755	 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
1756	 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
1757
1758Let's look at the output of ``abidiff``: ::
1759
1760	 $ abidiff libtest2-v0.so libtest2-v1.so
1761	 Functions changes summary: 0 Removed, 3 Changed, 0 Added functions
1762	 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1763
1764	 3 functions with some indirect sub-type change:
1765
1766	   [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1767	     parameter 0 of type 'struct S3' has sub-type changes:
1768	       size changed from 32 to 64 bits
1769	       1 base class insertion:
1770		 struct base_type
1771	       1 data member change:
1772		'int S3::m0' offset changed from 0 to 32
1773
1774	   [C]'function char func(S2*)' has some indirect sub-type changes:
1775	     parameter 0 of type 'S2*' has sub-type changes:
1776	       in pointed to type 'struct S2':
1777		 size changed from 32 to 64 bits
1778		 1 base class insertion:
1779		   struct base_type
1780		 1 data member change:
1781		  'int S2::m0' offset changed from 0 to 32
1782
1783	   [C]'function int func(S1&)' has some indirect sub-type changes:
1784	     parameter 0 of type 'S1&' has sub-type changes:
1785	       in referenced type 'struct S1':
1786		 size changed from 32 to 64 bits
1787		 1 base class insertion:
1788		   struct base_type
1789		 1 data member change:
1790		  'int S1::m0' offset changed from 0 to 32
1791	 $
1792
1793Let's tell ``abidiff`` to avoid showing us the differences on the
1794overloads of ``func`` that takes either a pointer or a reference.
1795For that, we author this simple suppression specification: ::
1796
1797	 $ cat -n libtest2.suppr
1798	      1	[suppress_function]
1799	      2	  name = func
1800	      3	  parameter = '0 S1&
1801	      4
1802	      5	[suppress_function]
1803	      6	  name = func
1804	      7	  parameter = '0 S2*
1805	 $
1806
1807And then let's invoke ``abidiff`` with the suppression
1808specification: ::
1809
1810  $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so
1811  Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1812  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1813
1814  1 function with some indirect sub-type change:
1815
1816	 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1817	   parameter 0 of type 'struct S3' has sub-type changes:
1818	     size changed from 32 to 64 bits
1819	     1 base class insertion:
1820	       struct base_type
1821	     1 data member change:
1822	      'int S3::m0' offset changed from 0 to 32
1823
1824
1825The suppression specification could be reduced using
1826:ref:`regular expressions <suppr_regexp_label>`: ::
1827
1828  $ cat -n libtest2-1.suppr
1829	    1	[suppress_function]
1830	    2	  name = func
1831	    3	  parameter = '0 /^S.(&|\\*)/
1832  $
1833
1834  $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so
1835  Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1836  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1837
1838  1 function with some indirect sub-type change:
1839
1840	 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1841	   parameter 0 of type 'struct S3' has sub-type changes:
1842	     size changed from 32 to 64 bits
1843	     1 base class insertion:
1844	       struct base_type
1845	     1 data member change:
1846	      'int S3::m0' offset changed from 0 to 32
1847
1848  $
1849
1850.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
1851
1852.. _Ini File Syntax: http://en.wikipedia.org/wiki/INI_file
1853
1854.. _GNU C Library: http://www.gnu.org/software/libc
1855