xref: /aosp_15_r20/external/stg/doc/comparison.md (revision 9e3b08ae94a55201065475453d799e8b1378bea6)
1*9e3b08aeSAndroid Build Coastguard Worker# Comparison
2*9e3b08aeSAndroid Build Coastguard Worker
3*9e3b08aeSAndroid Build Coastguard WorkerThis is implemented in `comparison.{h,cc}`.
4*9e3b08aeSAndroid Build Coastguard Worker
5*9e3b08aeSAndroid Build Coastguard WorkerGraph comparison is the basis of all STG difference reporting.
6*9e3b08aeSAndroid Build Coastguard Worker
7*9e3b08aeSAndroid Build Coastguard WorkerAll the various STG node attributes (such as `size` or `name`) and edge
8*9e3b08aeSAndroid Build Coastguard Workeridentifiers (whether explicit or not, such as function parameter index) can be
9*9e3b08aeSAndroid Build Coastguard Workerreduced to generic labels. This (over)simplification reduces the problem to
10*9e3b08aeSAndroid Build Coastguard Workersolve to:
11*9e3b08aeSAndroid Build Coastguard Worker
12*9e3b08aeSAndroid Build Coastguard Worker*   given two rooted directed graphs, containing labelled nodes and edges
13*9e3b08aeSAndroid Build Coastguard Worker*   generate a graph that encapsulates all the differences found by following
14*9e3b08aeSAndroid Build Coastguard Worker    matching pairs of edges
15*9e3b08aeSAndroid Build Coastguard Worker
16*9e3b08aeSAndroid Build Coastguard WorkerReport generation from such a graph is the subject of [Reporting](reporting.md).
17*9e3b08aeSAndroid Build Coastguard Worker
18*9e3b08aeSAndroid Build Coastguard WorkerSTG compares the graphs starting at the root nodes and recursing along edges
19*9e3b08aeSAndroid Build Coastguard Workerwith matching labels. The recursion stops at incomparable nodes (such as a
20*9e3b08aeSAndroid Build Coastguard Worker`struct` and `int`). Otherwise a comparison specific to the kind of node is
21*9e3b08aeSAndroid Build Coastguard Workerperformed.
22*9e3b08aeSAndroid Build Coastguard Worker
23*9e3b08aeSAndroid Build Coastguard WorkerGiven that the graph will in general not be a tree and may contain cycles, STG
24*9e3b08aeSAndroid Build Coastguard Worker
25*9e3b08aeSAndroid Build Coastguard Worker*   memoises comparisons with known results
26*9e3b08aeSAndroid Build Coastguard Worker*   detects comparison cycles and ensures correct termination and propagation of
27*9e3b08aeSAndroid Build Coastguard Worker    results
28*9e3b08aeSAndroid Build Coastguard Worker
29*9e3b08aeSAndroid Build Coastguard WorkerOverall, this ensures that any given pair of nodes (one from each graph) is
30*9e3b08aeSAndroid Build Coastguard Workercompared at most once. In the case of a small change to a typical ABI graph of
31*9e3b08aeSAndroid Build Coastguard Workersize *N*, *O(N)* node comparisons are performed.
32*9e3b08aeSAndroid Build Coastguard Worker
33*9e3b08aeSAndroid Build Coastguard Worker## Ignoring certain kinds of differences
34*9e3b08aeSAndroid Build Coastguard Worker
35*9e3b08aeSAndroid Build Coastguard WorkerIt has proved useful to add selective suppression of certain kinds of
36*9e3b08aeSAndroid Build Coastguard Workerdifferences, for distinct purposes.
37*9e3b08aeSAndroid Build Coastguard Worker
38*9e3b08aeSAndroid Build Coastguard Worker| **ignore**               | **directionality** | **purpose**               |
39*9e3b08aeSAndroid Build Coastguard Worker| ------------------------ | ------------------ | ------------------------- |
40*9e3b08aeSAndroid Build Coastguard Worker| interface addition       | asymmetric         | compatibility checking    |
41*9e3b08aeSAndroid Build Coastguard Worker| type definition addition | asymmetric         | compatibility checking    |
42*9e3b08aeSAndroid Build Coastguard Worker| primitive type encoding  | symmetric          | cross comparison noise    |
43*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : reduction                 :
44*9e3b08aeSAndroid Build Coastguard Worker| member size              | symmetric          | cross comparison noise    |
45*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : reduction                 :
46*9e3b08aeSAndroid Build Coastguard Worker| enum underlying type     | symmetric          | cross comparison noise    |
47*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : reduction                 :
48*9e3b08aeSAndroid Build Coastguard Worker| qualifier                | symmetric          | cross comparison noise    |
49*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : reduction                 :
50*9e3b08aeSAndroid Build Coastguard Worker| symbol CRC               | symmetric          | cross comparison noise    |
51*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : reduction                 :
52*9e3b08aeSAndroid Build Coastguard Worker| symbol type presence     | symmetric          | libabigail XML comparison |
53*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : noise reduction           :
54*9e3b08aeSAndroid Build Coastguard Worker| type declaration status  | symmetric          | libabigail XML comparison |
55*9e3b08aeSAndroid Build Coastguard Worker:                          :                    : noise reduction           :
56*9e3b08aeSAndroid Build Coastguard Worker
57*9e3b08aeSAndroid Build Coastguard WorkerThe first two options can be used to test whether one ABI is a subset of
58*9e3b08aeSAndroid Build Coastguard Workeranother.
59*9e3b08aeSAndroid Build Coastguard Worker
60*9e3b08aeSAndroid Build Coastguard WorkerIt can be useful to cross compare ABIs extracted in different ways to validate
61*9e3b08aeSAndroid Build Coastguard Workerthe fidelity of one ABI source against another. Where the models or
62*9e3b08aeSAndroid Build Coastguard Workerimplementations differ systematically, suppressing those differences will make
63*9e3b08aeSAndroid Build Coastguard Workerthe remainder more obvious.
64*9e3b08aeSAndroid Build Coastguard Worker
65*9e3b08aeSAndroid Build Coastguard WorkerThe libabigail versions used in Android's GKI project often generated ABIs with
66*9e3b08aeSAndroid Build Coastguard Workerspurious differences due to the disappearance (or reappearance) of type
67*9e3b08aeSAndroid Build Coastguard Workerdefinitions and (occasionally) symbol types. The corresponding ignore options
68*9e3b08aeSAndroid Build Coastguard Workerreplicate the behaviour of libabigail's `abidiff`.
69*9e3b08aeSAndroid Build Coastguard Worker
70*9e3b08aeSAndroid Build Coastguard Worker## Differences and difference graphs
71*9e3b08aeSAndroid Build Coastguard Worker
72*9e3b08aeSAndroid Build Coastguard WorkerWhen comparing a pair of nodes, each difference falls into one of the following
73*9e3b08aeSAndroid Build Coastguard Workercategories:
74*9e3b08aeSAndroid Build Coastguard Worker
75*9e3b08aeSAndroid Build Coastguard Worker*   node label - a purely local difference
76*9e3b08aeSAndroid Build Coastguard Worker*   matching edge - a recursive difference found by following edges with
77*9e3b08aeSAndroid Build Coastguard Worker    matching labels
78*9e3b08aeSAndroid Build Coastguard Worker*   added or removed labelled edges, where edges are identified by label -
79*9e3b08aeSAndroid Build Coastguard Worker    modelled as a recursive difference with a node absent on one side
80*9e3b08aeSAndroid Build Coastguard Worker
81*9e3b08aeSAndroid Build Coastguard WorkerEach node in an STG difference graph is one of the following[^1]:
82*9e3b08aeSAndroid Build Coastguard Worker
83*9e3b08aeSAndroid Build Coastguard Worker*   a node removal or addition, containing
84*9e3b08aeSAndroid Build Coastguard Worker    *   a reference to either a node in first graph or one in the second
85*9e3b08aeSAndroid Build Coastguard Worker*   a node change, containing
86*9e3b08aeSAndroid Build Coastguard Worker    *   a reference to two nodes, one in each of the two graphs
87*9e3b08aeSAndroid Build Coastguard Worker    *   a possibly-empty list of differences which can each be one of
88*9e3b08aeSAndroid Build Coastguard Worker        *   a node attribute difference in the form of some informative text
89*9e3b08aeSAndroid Build Coastguard Worker        *   an edge difference in the form of a link to a difference node
90*9e3b08aeSAndroid Build Coastguard Worker
91*9e3b08aeSAndroid Build Coastguard Worker[^1]: STG models comparisons as pairs of nodes where either node can be absent.
92*9e3b08aeSAndroid Build Coastguard Worker    The absent-absent comparison is used to represent "no change". All such
93*9e3b08aeSAndroid Build Coastguard Worker    edges, except those representing the root of a "no change" graph comparison,
94*9e3b08aeSAndroid Build Coastguard Worker    are pruned during diff graph creation.
95*9e3b08aeSAndroid Build Coastguard Worker
96*9e3b08aeSAndroid Build Coastguard WorkerNote that STG's difference nodes are *unkinded*, there is only one kind of
97*9e3b08aeSAndroid Build Coastguard Workerdifference node, unlike STG's data nodes where there is a separate kind of node
98*9e3b08aeSAndroid Build Coastguard Workerfor each kind of C type etc.
99*9e3b08aeSAndroid Build Coastguard Worker
100*9e3b08aeSAndroid Build Coastguard Worker## Matching and comparing collections of edges
101*9e3b08aeSAndroid Build Coastguard Worker
102*9e3b08aeSAndroid Build Coastguard WorkerWhile an algorithm based on generic label comparison will work, there are a
103*9e3b08aeSAndroid Build Coastguard Workercouple of issues:
104*9e3b08aeSAndroid Build Coastguard Worker
105*9e3b08aeSAndroid Build Coastguard Worker*   collections of outgoing edges may not have an obvious label to assign
106*9e3b08aeSAndroid Build Coastguard Worker    (multiple anonymous members of a `struct`, for example)
107*9e3b08aeSAndroid Build Coastguard Worker*   edges are often ordered (parameters and members, for example) and we want to
108*9e3b08aeSAndroid Build Coastguard Worker    preserve this order when reporting differences
109*9e3b08aeSAndroid Build Coastguard Worker
110*9e3b08aeSAndroid Build Coastguard WorkerComparing two pointer types is straightforward, just compare the pointed-to
111*9e3b08aeSAndroid Build Coastguard Workertypes. However, symbol tables, function arguments and struct members all require
112*9e3b08aeSAndroid Build Coastguard Workercomparisons of multiple entities simultaneously.
113*9e3b08aeSAndroid Build Coastguard Worker
114*9e3b08aeSAndroid Build Coastguard WorkerSTG compares edge aggregates as follows:
115*9e3b08aeSAndroid Build Coastguard Worker
116*9e3b08aeSAndroid Build Coastguard Worker*   arrays (like function arguments): by index, comparing recursively items with
117*9e3b08aeSAndroid Build Coastguard Worker    the same index, reporting removals and additions of the remaining items
118*9e3b08aeSAndroid Build Coastguard Worker*   maps (like the symbol table): by key, comparing recursively items with
119*9e3b08aeSAndroid Build Coastguard Worker    matching keys, reporting removals and additions of unmatched items
120*9e3b08aeSAndroid Build Coastguard Worker*   otherwise synthesise a key for comparison, compare by key, report
121*9e3b08aeSAndroid Build Coastguard Worker    differences in the original order of items being compared (favouring the
122*9e3b08aeSAndroid Build Coastguard Worker    second list's order over the first's); the reordering is an *O(n²)*
123*9e3b08aeSAndroid Build Coastguard Worker    operation and it might be possible to adapt the more general Myer's diff
124*9e3b08aeSAndroid Build Coastguard Worker    algorithm to reduce this
125*9e3b08aeSAndroid Build Coastguard Worker
126*9e3b08aeSAndroid Build Coastguard Worker## Implementation Details
127*9e3b08aeSAndroid Build Coastguard Worker
128*9e3b08aeSAndroid Build Coastguard WorkerComparison is mostly done pair-wise recursively with a DFS, by the function
129*9e3b08aeSAndroid Build Coastguard Workerobject `CompareWorker` and with the help of the [SCC finder](scc.md).
130*9e3b08aeSAndroid Build Coastguard Worker
131*9e3b08aeSAndroid Build Coastguard WorkerThe algorithm divides responsibility between `operator()(Id, Id)` and various
132*9e3b08aeSAndroid Build Coastguard Worker`operator()(Node, Node)` methods. There are also various helpers in and outside
133*9e3b08aeSAndroid Build Coastguard Worker`CompareWorker`.
134*9e3b08aeSAndroid Build Coastguard Worker
135*9e3b08aeSAndroid Build Coastguard WorkerThe `Result` type encapsulates the difference between two nodes being compared.
136*9e3b08aeSAndroid Build Coastguard WorkerIt contains both a list (`Diff`) of differences (`DiffDetail`) and a boolean
137*9e3b08aeSAndroid Build Coastguard Workerequality outcome. The latter is used to propagate inequality information in the
138*9e3b08aeSAndroid Build Coastguard Workerpresence of cycles in the diff comparison graph.
139*9e3b08aeSAndroid Build Coastguard Worker
140*9e3b08aeSAndroid Build Coastguard Worker### `operator()(Node, Node)`
141*9e3b08aeSAndroid Build Coastguard Worker
142*9e3b08aeSAndroid Build Coastguard WorkerSpecialised for each `Node` type, these methods have the job of computing local
143*9e3b08aeSAndroid Build Coastguard Workerdifferences, matching edges and obtaining edge differences from recursive calls
144*9e3b08aeSAndroid Build Coastguard Workerto `operator()(Id, Id)` (or `Removed` and `Added`, if edge labels are
145*9e3b08aeSAndroid Build Coastguard Workerunmatched).
146*9e3b08aeSAndroid Build Coastguard Worker
147*9e3b08aeSAndroid Build Coastguard WorkerLocal differences can easily be rendered as text, but edge differences need
148*9e3b08aeSAndroid Build Coastguard Workerrecursive calls, the results of which are merged into the local differences
149*9e3b08aeSAndroid Build Coastguard Worker`Result` with helper methods.
150*9e3b08aeSAndroid Build Coastguard Worker
151*9e3b08aeSAndroid Build Coastguard WorkerThese methods form the bulk of the comparison code, so in general we want them
152*9e3b08aeSAndroid Build Coastguard Workerto be as small as possible, containing no boilerplate and simply mirroring the
153*9e3b08aeSAndroid Build Coastguard Workernode data. The helper functions were therefore chosen for power, laziness and
154*9e3b08aeSAndroid Build Coastguard Workerconcision.
155*9e3b08aeSAndroid Build Coastguard Worker
156*9e3b08aeSAndroid Build Coastguard Worker### `Added` and `Removed`
157*9e3b08aeSAndroid Build Coastguard Worker
158*9e3b08aeSAndroid Build Coastguard WorkerThese take care of comparisons where one side is absent.
159*9e3b08aeSAndroid Build Coastguard Worker
160*9e3b08aeSAndroid Build Coastguard WorkerThere are several reasons for not folding this functionality into `operator(Id,
161*9e3b08aeSAndroid Build Coastguard WorkerId)` itself:
162*9e3b08aeSAndroid Build Coastguard Worker
163*9e3b08aeSAndroid Build Coastguard Worker*   it would result in unnecessary extra work as its callers would need to pack
164*9e3b08aeSAndroid Build Coastguard Worker    and the function would need to unpack `optional<Id>` arguments
165*9e3b08aeSAndroid Build Coastguard Worker*   added and removed nodes have none of the other interesting features that it
166*9e3b08aeSAndroid Build Coastguard Worker    handles
167*9e3b08aeSAndroid Build Coastguard Worker*   `Added` and `Removed` don't need to decorate their return values with any
168*9e3b08aeSAndroid Build Coastguard Worker    difference information
169*9e3b08aeSAndroid Build Coastguard Worker
170*9e3b08aeSAndroid Build Coastguard Worker### `Defined`
171*9e3b08aeSAndroid Build Coastguard Worker
172*9e3b08aeSAndroid Build Coastguard WorkerThis takes care of comparisons of user-defined types which may be forward
173*9e3b08aeSAndroid Build Coastguard Workerdeclarations or full definitions.
174*9e3b08aeSAndroid Build Coastguard Worker
175*9e3b08aeSAndroid Build Coastguard Worker### `Nodes`
176*9e3b08aeSAndroid Build Coastguard Worker
177*9e3b08aeSAndroid Build Coastguard WorkerThese take care of comparisons of sequences of arbitrary nodes (or enumerators).
178*9e3b08aeSAndroid Build Coastguard Worker
179*9e3b08aeSAndroid Build Coastguard WorkerSTG uses "matching keys" to reduce the problem of comparing sequences to
180*9e3b08aeSAndroid Build Coastguard Workercomparing maps. It attempts to preserve original sequence order as described in
181*9e3b08aeSAndroid Build Coastguard Worker`order.h`.
182*9e3b08aeSAndroid Build Coastguard Worker
183*9e3b08aeSAndroid Build Coastguard Worker### `operator(Id, Id)`
184*9e3b08aeSAndroid Build Coastguard Worker
185*9e3b08aeSAndroid Build Coastguard WorkerThis controls recursion and handles some special cases before delegating to some
186*9e3b08aeSAndroid Build Coastguard Worker`operator()(Node, Node)` in the "normal" case.
187*9e3b08aeSAndroid Build Coastguard Worker
188*9e3b08aeSAndroid Build Coastguard WorkerIt takes care of the following:
189*9e3b08aeSAndroid Build Coastguard Worker
190*9e3b08aeSAndroid Build Coastguard Worker*   revisited, completed comparisons
191*9e3b08aeSAndroid Build Coastguard Worker*   revisited, in-progress comparison
192*9e3b08aeSAndroid Build Coastguard Worker*   qualified types
193*9e3b08aeSAndroid Build Coastguard Worker*   typedefs
194*9e3b08aeSAndroid Build Coastguard Worker*   incomparable and comparable nodes
195*9e3b08aeSAndroid Build Coastguard Worker*   comparison cycles
196*9e3b08aeSAndroid Build Coastguard Worker
197*9e3b08aeSAndroid Build Coastguard WorkerNote that the non-trivial special cases relating to typedefs and qualified types
198*9e3b08aeSAndroid Build Coastguard Worker(and their current concrete representations) require non-parallel traversals of
199*9e3b08aeSAndroid Build Coastguard Workerthe graphs being compared; this is the only place where the comparison is not
200*9e3b08aeSAndroid Build Coastguard Workerpurely structural.
201*9e3b08aeSAndroid Build Coastguard Worker
202*9e3b08aeSAndroid Build Coastguard Worker#### Revisited Nodes and Recursive Comparison
203*9e3b08aeSAndroid Build Coastguard Worker
204*9e3b08aeSAndroid Build Coastguard WorkerSTG comparison relies on `SCC` to control recursion and behaviour in the face of
205*9e3b08aeSAndroid Build Coastguard Workergraphs containing arbitrary cycles. Any difference found affecting one node in a
206*9e3b08aeSAndroid Build Coastguard Workercomparison cycle affects all nodes in that cycle.
207*9e3b08aeSAndroid Build Coastguard Worker
208*9e3b08aeSAndroid Build Coastguard WorkerExcluding the two special cases documented in the following sections, the
209*9e3b08aeSAndroid Build Coastguard Workercomparison steps are approximately:
210*9e3b08aeSAndroid Build Coastguard Worker
211*9e3b08aeSAndroid Build Coastguard Worker1.  if the comparison already has a known result then return this
212*9e3b08aeSAndroid Build Coastguard Worker2.  if the comparison already is in progress then return a potential difference
213*9e3b08aeSAndroid Build Coastguard Worker3.  start node visit, register the node with the SCC finder
214*9e3b08aeSAndroid Build Coastguard Worker    1.  (special handling of qualified types and typedefs)
215*9e3b08aeSAndroid Build Coastguard Worker    2.  incomparable nodes (such as a `struct` and an `int`) go to `Mismatch`
216*9e3b08aeSAndroid Build Coastguard Worker        which returns a difference; there is no further recursion
217*9e3b08aeSAndroid Build Coastguard Worker    3.  otherwise delegate node comparison to a node-specific function; with
218*9e3b08aeSAndroid Build Coastguard Worker        possible recursion
219*9e3b08aeSAndroid Build Coastguard Worker    4.  the comparison result here is tentative, due to potential cycles
220*9e3b08aeSAndroid Build Coastguard Worker4.  finish node visit, informing the SCC finder
221*9e3b08aeSAndroid Build Coastguard Worker5.  if an SCC was closed, we've just finished its root comparison
222*9e3b08aeSAndroid Build Coastguard Worker    1.  root compared equal? discard unwanted potential differences
223*9e3b08aeSAndroid Build Coastguard Worker    2.  difference found? record confirmed differences
224*9e3b08aeSAndroid Build Coastguard Worker    3.  record all its comparison results as final
225*9e3b08aeSAndroid Build Coastguard Worker6.  return result (which will be final if an SCC was closed)
226*9e3b08aeSAndroid Build Coastguard Worker
227*9e3b08aeSAndroid Build Coastguard Worker#### Typedefs
228*9e3b08aeSAndroid Build Coastguard Worker
229*9e3b08aeSAndroid Build Coastguard WorkerThis special handling is subject to change.
230*9e3b08aeSAndroid Build Coastguard Worker
231*9e3b08aeSAndroid Build Coastguard Worker*   `typedef` foo bar ⇔ foo
232*9e3b08aeSAndroid Build Coastguard Worker
233*9e3b08aeSAndroid Build Coastguard WorkerTypedefs are named type aliases which cannot refer to themselves or later
234*9e3b08aeSAndroid Build Coastguard Workerdefined types. The referred-to type is exactly identical to the typedef. So for
235*9e3b08aeSAndroid Build Coastguard Workerdifference *finding*, typedefs should just be resolved and skipped over.
236*9e3b08aeSAndroid Build Coastguard WorkerHowever, for *reporting*, it may be still useful to say where a difference came
237*9e3b08aeSAndroid Build Coastguard Workerfrom. This requires extra handling to collect the typedef names on each side of
238*9e3b08aeSAndroid Build Coastguard Workerthe comparison, when there is something to report.
239*9e3b08aeSAndroid Build Coastguard Worker
240*9e3b08aeSAndroid Build Coastguard WorkerIf `operator()(Id, Id)` sees a comparison involving a typedef, it resolves
241*9e3b08aeSAndroid Build Coastguard Workertypedef chains on both sides and keeps track of the names. Then it calls itself
242*9e3b08aeSAndroid Build Coastguard Workerrecursively. If the result is no-diff, it returns no-diff, otherwise, it reports
243*9e3b08aeSAndroid Build Coastguard Workerthe differences between the types at the end of the typedef chains.
244*9e3b08aeSAndroid Build Coastguard Worker
245*9e3b08aeSAndroid Build Coastguard WorkerAn alternative would be to genuinely just follow the epsilons. Store the
246*9e3b08aeSAndroid Build Coastguard Workertypedefs in the diff tree but record the comparison of what they resolve to. The
247*9e3b08aeSAndroid Build Coastguard Workerpresentation layer can decorate the comparison text with resolution chains.
248*9e3b08aeSAndroid Build Coastguard Worker
249*9e3b08aeSAndroid Build Coastguard WorkerNote that qualified typedefs present extra complications.
250*9e3b08aeSAndroid Build Coastguard Worker
251*9e3b08aeSAndroid Build Coastguard Worker#### Qualified Types
252*9e3b08aeSAndroid Build Coastguard Worker
253*9e3b08aeSAndroid Build Coastguard WorkerThis special handling is subject to change.
254*9e3b08aeSAndroid Build Coastguard Worker
255*9e3b08aeSAndroid Build Coastguard Worker*   `const` → `volatile` → foo ⇔ `volatile` → `const` → foo
256*9e3b08aeSAndroid Build Coastguard Worker
257*9e3b08aeSAndroid Build Coastguard WorkerSTG currently represents type qualifiers as separate, individual nodes. They are
258*9e3b08aeSAndroid Build Coastguard Workerrelevant for finding differences but there may be no guarantee of the order in
259*9e3b08aeSAndroid Build Coastguard Workerwhich they will appear. For diff reporting, STG currently reports added and
260*9e3b08aeSAndroid Build Coastguard Workerremoved qualifiers but also compares the underlying types.
261*9e3b08aeSAndroid Build Coastguard Worker
262*9e3b08aeSAndroid Build Coastguard WorkerThis implies that when faced with a comparison involving a qualifier,
263*9e3b08aeSAndroid Build Coastguard Worker`operator()(Id, Id)` should collect and compare all qualifiers on both sides and
264*9e3b08aeSAndroid Build Coastguard Workertreat the types as compound objects consisting of their qualifiers and the
265*9e3b08aeSAndroid Build Coastguard Workerunderlying types, either or both of which may have differences to report.
266*9e3b08aeSAndroid Build Coastguard WorkerComparing the underlying types requires recursive calls.
267*9e3b08aeSAndroid Build Coastguard Worker
268*9e3b08aeSAndroid Build Coastguard WorkerNote that qualified typedefs present extra complications.
269*9e3b08aeSAndroid Build Coastguard Worker
270*9e3b08aeSAndroid Build Coastguard Worker#### Qualified typedefs
271*9e3b08aeSAndroid Build Coastguard Worker
272*9e3b08aeSAndroid Build Coastguard WorkerSTG does not currently do anything special for qualified typedefs which can have
273*9e3b08aeSAndroid Build Coastguard Workersubtle and surprising behaviours. For example:
274*9e3b08aeSAndroid Build Coastguard Worker
275*9e3b08aeSAndroid Build Coastguard WorkerBefore:
276*9e3b08aeSAndroid Build Coastguard Worker
277*9e3b08aeSAndroid Build Coastguard Worker```c++
278*9e3b08aeSAndroid Build Coastguard Workerconst int quux;
279*9e3b08aeSAndroid Build Coastguard Worker```
280*9e3b08aeSAndroid Build Coastguard Worker
281*9e3b08aeSAndroid Build Coastguard WorkerAfter 1:
282*9e3b08aeSAndroid Build Coastguard Worker
283*9e3b08aeSAndroid Build Coastguard Worker```c++
284*9e3b08aeSAndroid Build Coastguard Workertypedef int foo;
285*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
286*9e3b08aeSAndroid Build Coastguard Worker```
287*9e3b08aeSAndroid Build Coastguard Worker
288*9e3b08aeSAndroid Build Coastguard WorkerAfter 2:
289*9e3b08aeSAndroid Build Coastguard Worker
290*9e3b08aeSAndroid Build Coastguard Worker```c++
291*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo;
292*9e3b08aeSAndroid Build Coastguard Workerfoo quux;
293*9e3b08aeSAndroid Build Coastguard Worker```
294*9e3b08aeSAndroid Build Coastguard Worker
295*9e3b08aeSAndroid Build Coastguard WorkerAfter 3:
296*9e3b08aeSAndroid Build Coastguard Worker
297*9e3b08aeSAndroid Build Coastguard Worker```c++
298*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo;
299*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
300*9e3b08aeSAndroid Build Coastguard Worker```
301*9e3b08aeSAndroid Build Coastguard Worker
302*9e3b08aeSAndroid Build Coastguard WorkerIn all cases above, the type of `quux` is unchanged. These examples strongly
303*9e3b08aeSAndroid Build Coastguard Workersuggest that a better model of C types would involve tracking qualification as a
304*9e3b08aeSAndroid Build Coastguard Workerdecoration present on every type node, including typedefs.
305*9e3b08aeSAndroid Build Coastguard Worker
306*9e3b08aeSAndroid Build Coastguard WorkerNote that this behaviour implies C's type system is not purely constructive as
307*9e3b08aeSAndroid Build Coastguard Workerthere is machinery to discard duplicate qualifiers which would be illegal
308*9e3b08aeSAndroid Build Coastguard Workerelsewhere.
309*9e3b08aeSAndroid Build Coastguard Worker
310*9e3b08aeSAndroid Build Coastguard WorkerFor the moment, we can pretend that outer qualifications are always significant,
311*9e3b08aeSAndroid Build Coastguard Workereven though they may be absorbed by inner ones, and risk occasional false
312*9e3b08aeSAndroid Build Coastguard Workerpositives.
313*9e3b08aeSAndroid Build Coastguard Worker
314*9e3b08aeSAndroid Build Coastguard WorkerA worse case is:
315*9e3b08aeSAndroid Build Coastguard Worker
316*9e3b08aeSAndroid Build Coastguard WorkerBefore:
317*9e3b08aeSAndroid Build Coastguard Worker
318*9e3b08aeSAndroid Build Coastguard Worker```c++
319*9e3b08aeSAndroid Build Coastguard Workerconst int quux[];
320*9e3b08aeSAndroid Build Coastguard Worker```
321*9e3b08aeSAndroid Build Coastguard Worker
322*9e3b08aeSAndroid Build Coastguard WorkerAfter 1:
323*9e3b08aeSAndroid Build Coastguard Worker
324*9e3b08aeSAndroid Build Coastguard Worker```c++
325*9e3b08aeSAndroid Build Coastguard Workertypedef int foo[];
326*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
327*9e3b08aeSAndroid Build Coastguard Worker```
328*9e3b08aeSAndroid Build Coastguard Worker
329*9e3b08aeSAndroid Build Coastguard WorkerAfter 2:
330*9e3b08aeSAndroid Build Coastguard Worker
331*9e3b08aeSAndroid Build Coastguard Worker```c++
332*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo[];
333*9e3b08aeSAndroid Build Coastguard Workerfoo quux;
334*9e3b08aeSAndroid Build Coastguard Worker```
335*9e3b08aeSAndroid Build Coastguard Worker
336*9e3b08aeSAndroid Build Coastguard WorkerAfter 3:
337*9e3b08aeSAndroid Build Coastguard Worker
338*9e3b08aeSAndroid Build Coastguard Worker```c++
339*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo[];
340*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
341*9e3b08aeSAndroid Build Coastguard Worker```
342*9e3b08aeSAndroid Build Coastguard Worker
343*9e3b08aeSAndroid Build Coastguard WorkerAll the `quux` are identically typed. There is an additional wart that what
344*9e3b08aeSAndroid Build Coastguard Workerwould normally be illegal qualifiers on an array type instead decorate its
345*9e3b08aeSAndroid Build Coastguard Workerelement type.
346*9e3b08aeSAndroid Build Coastguard Worker
347*9e3b08aeSAndroid Build Coastguard WorkerFinally, worst is:
348*9e3b08aeSAndroid Build Coastguard Worker
349*9e3b08aeSAndroid Build Coastguard WorkerBefore:
350*9e3b08aeSAndroid Build Coastguard Worker
351*9e3b08aeSAndroid Build Coastguard Worker```c++
352*9e3b08aeSAndroid Build Coastguard Workerconst int quux();
353*9e3b08aeSAndroid Build Coastguard Worker```
354*9e3b08aeSAndroid Build Coastguard Worker
355*9e3b08aeSAndroid Build Coastguard WorkerAfter 1:
356*9e3b08aeSAndroid Build Coastguard Worker
357*9e3b08aeSAndroid Build Coastguard Worker```c++
358*9e3b08aeSAndroid Build Coastguard Workertypedef int foo();
359*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
360*9e3b08aeSAndroid Build Coastguard Worker```
361*9e3b08aeSAndroid Build Coastguard Worker
362*9e3b08aeSAndroid Build Coastguard WorkerAfter 2:
363*9e3b08aeSAndroid Build Coastguard Worker
364*9e3b08aeSAndroid Build Coastguard Worker```c++
365*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo();
366*9e3b08aeSAndroid Build Coastguard Workerfoo quux;
367*9e3b08aeSAndroid Build Coastguard Worker```
368*9e3b08aeSAndroid Build Coastguard Worker
369*9e3b08aeSAndroid Build Coastguard WorkerAfter 3:
370*9e3b08aeSAndroid Build Coastguard Worker
371*9e3b08aeSAndroid Build Coastguard Worker```c++
372*9e3b08aeSAndroid Build Coastguard Workertypedef const int foo();
373*9e3b08aeSAndroid Build Coastguard Workerconst foo quux;
374*9e3b08aeSAndroid Build Coastguard Worker```
375*9e3b08aeSAndroid Build Coastguard Worker
376*9e3b08aeSAndroid Build Coastguard WorkerThe two `const foo quux` cases invoke undefined behaviour. The consistently
377*9e3b08aeSAndroid Build Coastguard Workercrazy behaviour would have been to decorate the return type instead.
378*9e3b08aeSAndroid Build Coastguard Worker
379*9e3b08aeSAndroid Build Coastguard WorkerThe "worstest" case is GCC allowing the specification of typedef alignment
380*9e3b08aeSAndroid Build Coastguard Workerdifferent to the defining type. This abomination should not exist and should
381*9e3b08aeSAndroid Build Coastguard Workernever be used. Alignment is not currently modelled by STG.
382*9e3b08aeSAndroid Build Coastguard Worker
383*9e3b08aeSAndroid Build Coastguard Worker### Diff helpers
384*9e3b08aeSAndroid Build Coastguard Worker
385*9e3b08aeSAndroid Build Coastguard WorkerThese are mainly used by the `CompareWorker::operator()(Node, Node)` methods.
386*9e3b08aeSAndroid Build Coastguard Worker
387*9e3b08aeSAndroid Build Coastguard Worker*   `MarkIncomparable` - nodes are just different
388*9e3b08aeSAndroid Build Coastguard Worker*   `AddNodeDiff` - add node difference, unconditionally
389*9e3b08aeSAndroid Build Coastguard Worker*   `AddEdgeDiff` - add edge difference (addition or removal), unconditionally
390*9e3b08aeSAndroid Build Coastguard Worker*   `MaybeAddNodeDiff` - add node difference (label change), conditionally
391*9e3b08aeSAndroid Build Coastguard Worker*   `MaybeAddEdgeDiff` - add matching edge recursive difference, conditionally
392*9e3b08aeSAndroid Build Coastguard Worker
393*9e3b08aeSAndroid Build Coastguard WorkerVariants are possible where text is generated lazily on a recursive diff being
394*9e3b08aeSAndroid Build Coastguard Workerfound, as are ones where labels are compared and serialised only if different.
395*9e3b08aeSAndroid Build Coastguard Worker
396*9e3b08aeSAndroid Build Coastguard Worker## Diff Presentation
397*9e3b08aeSAndroid Build Coastguard Worker
398*9e3b08aeSAndroid Build Coastguard WorkerIn general, there are two problems to solve:
399*9e3b08aeSAndroid Build Coastguard Worker
400*9e3b08aeSAndroid Build Coastguard Worker*   generating suitable text, for
401*9e3b08aeSAndroid Build Coastguard Worker    *   nodes and edges
402*9e3b08aeSAndroid Build Coastguard Worker    *   node and edge differences
403*9e3b08aeSAndroid Build Coastguard Worker*   building a report with some meaningful structure
404*9e3b08aeSAndroid Build Coastguard Worker
405*9e3b08aeSAndroid Build Coastguard WorkerNode and edge description and report structure are the responsibility of the
406*9e3b08aeSAndroid Build Coastguard Worker*reporting* code. See [Naming](naming.md) for more detailed notes on node
407*9e3b08aeSAndroid Build Coastguard Workerdescription, mainly C type name syntax.
408*9e3b08aeSAndroid Build Coastguard Worker
409*9e3b08aeSAndroid Build Coastguard WorkerSeveral report formats are supported and the simplest is (omitting various
410*9e3b08aeSAndroid Build Coastguard Workercomplications) a rendering of a difference graph as a difference *tree* where
411*9e3b08aeSAndroid Build Coastguard Workerrevisiting nodes is avoided by reporting 2 additional artificial kinds of
412*9e3b08aeSAndroid Build Coastguard Workerdifference:
413*9e3b08aeSAndroid Build Coastguard Worker
414*9e3b08aeSAndroid Build Coastguard Worker1.  already reported - to handle diff sharing
415*9e3b08aeSAndroid Build Coastguard Worker2.  being compared - to handle diff cycles
416*9e3b08aeSAndroid Build Coastguard Worker
417*9e3b08aeSAndroid Build Coastguard WorkerThe various formats are not documented further here.
418*9e3b08aeSAndroid Build Coastguard Worker
419*9e3b08aeSAndroid Build Coastguard WorkerFinally, node and edge difference description is currently the responsibility of
420*9e3b08aeSAndroid Build Coastguard Workerthe *comparison* code. This may change in the future, but might require a typed
421*9e3b08aeSAndroid Build Coastguard Workerdifference graph.
422