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