xref: /aosp_15_r20/external/stg/comparison.h (revision 9e3b08ae94a55201065475453d799e8b1378bea6)
1*9e3b08aeSAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2*9e3b08aeSAndroid Build Coastguard Worker // -*- mode: C++ -*-
3*9e3b08aeSAndroid Build Coastguard Worker //
4*9e3b08aeSAndroid Build Coastguard Worker // Copyright 2020-2024 Google LLC
5*9e3b08aeSAndroid Build Coastguard Worker //
6*9e3b08aeSAndroid Build Coastguard Worker // Licensed under the Apache License v2.0 with LLVM Exceptions (the
7*9e3b08aeSAndroid Build Coastguard Worker // "License"); you may not use this file except in compliance with the
8*9e3b08aeSAndroid Build Coastguard Worker // License.  You may obtain a copy of the License at
9*9e3b08aeSAndroid Build Coastguard Worker //
10*9e3b08aeSAndroid Build Coastguard Worker //     https://llvm.org/LICENSE.txt
11*9e3b08aeSAndroid Build Coastguard Worker //
12*9e3b08aeSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
13*9e3b08aeSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
14*9e3b08aeSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*9e3b08aeSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
16*9e3b08aeSAndroid Build Coastguard Worker // limitations under the License.
17*9e3b08aeSAndroid Build Coastguard Worker //
18*9e3b08aeSAndroid Build Coastguard Worker // Author: Maria Teguiani
19*9e3b08aeSAndroid Build Coastguard Worker // Author: Giuliano Procida
20*9e3b08aeSAndroid Build Coastguard Worker // Author: Ignes Simeonova
21*9e3b08aeSAndroid Build Coastguard Worker 
22*9e3b08aeSAndroid Build Coastguard Worker #ifndef STG_COMPARISON_H_
23*9e3b08aeSAndroid Build Coastguard Worker #define STG_COMPARISON_H_
24*9e3b08aeSAndroid Build Coastguard Worker 
25*9e3b08aeSAndroid Build Coastguard Worker #include <cstddef>
26*9e3b08aeSAndroid Build Coastguard Worker #include <cstdint>
27*9e3b08aeSAndroid Build Coastguard Worker #include <functional>
28*9e3b08aeSAndroid Build Coastguard Worker #include <optional>
29*9e3b08aeSAndroid Build Coastguard Worker #include <ostream>
30*9e3b08aeSAndroid Build Coastguard Worker #include <string>
31*9e3b08aeSAndroid Build Coastguard Worker #include <string_view>
32*9e3b08aeSAndroid Build Coastguard Worker #include <unordered_map>
33*9e3b08aeSAndroid Build Coastguard Worker #include <utility>
34*9e3b08aeSAndroid Build Coastguard Worker #include <vector>
35*9e3b08aeSAndroid Build Coastguard Worker 
36*9e3b08aeSAndroid Build Coastguard Worker #include "graph.h"
37*9e3b08aeSAndroid Build Coastguard Worker #include "runtime.h"
38*9e3b08aeSAndroid Build Coastguard Worker 
39*9e3b08aeSAndroid Build Coastguard Worker namespace stg {
40*9e3b08aeSAndroid Build Coastguard Worker namespace diff {
41*9e3b08aeSAndroid Build Coastguard Worker 
42*9e3b08aeSAndroid Build Coastguard Worker struct Ignore {
43*9e3b08aeSAndroid Build Coastguard Worker   enum Value {
44*9e3b08aeSAndroid Build Coastguard Worker     // noise reduction
45*9e3b08aeSAndroid Build Coastguard Worker     SYMBOL_TYPE_PRESENCE,
46*9e3b08aeSAndroid Build Coastguard Worker     TYPE_DECLARATION_STATUS,
47*9e3b08aeSAndroid Build Coastguard Worker     PRIMITIVE_TYPE_ENCODING,
48*9e3b08aeSAndroid Build Coastguard Worker     MEMBER_SIZE,
49*9e3b08aeSAndroid Build Coastguard Worker     ENUM_UNDERLYING_TYPE,
50*9e3b08aeSAndroid Build Coastguard Worker     QUALIFIER,
51*9e3b08aeSAndroid Build Coastguard Worker     SYMBOL_CRC,
52*9e3b08aeSAndroid Build Coastguard Worker     // ABI compatibility testing
53*9e3b08aeSAndroid Build Coastguard Worker     INTERFACE_ADDITION,
54*9e3b08aeSAndroid Build Coastguard Worker     TYPE_DEFINITION_ADDITION,
55*9e3b08aeSAndroid Build Coastguard Worker   };
56*9e3b08aeSAndroid Build Coastguard Worker 
57*9e3b08aeSAndroid Build Coastguard Worker   using Bitset = uint16_t;
58*9e3b08aeSAndroid Build Coastguard Worker 
59*9e3b08aeSAndroid Build Coastguard Worker   Ignore() = default;
60*9e3b08aeSAndroid Build Coastguard Worker   template <typename... Values>
IgnoreIgnore61*9e3b08aeSAndroid Build Coastguard Worker   explicit Ignore(Values... values) {
62*9e3b08aeSAndroid Build Coastguard Worker     for (auto value : {values...}) {
63*9e3b08aeSAndroid Build Coastguard Worker       Set(value);
64*9e3b08aeSAndroid Build Coastguard Worker     }
65*9e3b08aeSAndroid Build Coastguard Worker   }
66*9e3b08aeSAndroid Build Coastguard Worker 
SetIgnore67*9e3b08aeSAndroid Build Coastguard Worker   void Set(Value other) {
68*9e3b08aeSAndroid Build Coastguard Worker     bitset = bitset | (1 << other);
69*9e3b08aeSAndroid Build Coastguard Worker   }
TestIgnore70*9e3b08aeSAndroid Build Coastguard Worker   bool Test(Value other) const {
71*9e3b08aeSAndroid Build Coastguard Worker     return (bitset & (1 << other)) != 0;
72*9e3b08aeSAndroid Build Coastguard Worker   }
73*9e3b08aeSAndroid Build Coastguard Worker 
74*9e3b08aeSAndroid Build Coastguard Worker   Bitset bitset = 0;
75*9e3b08aeSAndroid Build Coastguard Worker };
76*9e3b08aeSAndroid Build Coastguard Worker 
77*9e3b08aeSAndroid Build Coastguard Worker std::optional<Ignore::Value> ParseIgnore(std::string_view ignore);
78*9e3b08aeSAndroid Build Coastguard Worker 
79*9e3b08aeSAndroid Build Coastguard Worker struct IgnoreUsage {};
80*9e3b08aeSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, IgnoreUsage);
81*9e3b08aeSAndroid Build Coastguard Worker 
82*9e3b08aeSAndroid Build Coastguard Worker using Comparison = std::pair<std::optional<Id>, std::optional<Id>>;
83*9e3b08aeSAndroid Build Coastguard Worker 
84*9e3b08aeSAndroid Build Coastguard Worker struct DiffDetail {
DiffDetailDiffDetail85*9e3b08aeSAndroid Build Coastguard Worker   DiffDetail(const std::string& text, const Comparison& edge)
86*9e3b08aeSAndroid Build Coastguard Worker       : text(text), edge(edge) {}
87*9e3b08aeSAndroid Build Coastguard Worker   std::string text;
88*9e3b08aeSAndroid Build Coastguard Worker   Comparison edge;
89*9e3b08aeSAndroid Build Coastguard Worker };
90*9e3b08aeSAndroid Build Coastguard Worker 
91*9e3b08aeSAndroid Build Coastguard Worker struct Diff {
92*9e3b08aeSAndroid Build Coastguard Worker   // This diff node corresponds to an entity that is reportable, if it or any of
93*9e3b08aeSAndroid Build Coastguard Worker   // its children (excluding reportable ones) has changed.
94*9e3b08aeSAndroid Build Coastguard Worker   bool holds_changes = false;
95*9e3b08aeSAndroid Build Coastguard Worker   // This diff node contains a local (non-recursive) change.
96*9e3b08aeSAndroid Build Coastguard Worker   bool has_changes = false;
97*9e3b08aeSAndroid Build Coastguard Worker   std::vector<DiffDetail> details;
98*9e3b08aeSAndroid Build Coastguard Worker 
AddDiff99*9e3b08aeSAndroid Build Coastguard Worker   void Add(const std::string& text, const Comparison& comparison) {
100*9e3b08aeSAndroid Build Coastguard Worker     details.emplace_back(text, comparison);
101*9e3b08aeSAndroid Build Coastguard Worker   }
102*9e3b08aeSAndroid Build Coastguard Worker };
103*9e3b08aeSAndroid Build Coastguard Worker 
104*9e3b08aeSAndroid Build Coastguard Worker struct HashComparison {
operatorHashComparison105*9e3b08aeSAndroid Build Coastguard Worker   size_t operator()(const Comparison& comparison) const {
106*9e3b08aeSAndroid Build Coastguard Worker     size_t seed = 0;
107*9e3b08aeSAndroid Build Coastguard Worker     const std::hash<std::optional<Id>> h;
108*9e3b08aeSAndroid Build Coastguard Worker     combine_hash(seed, h(comparison.first));
109*9e3b08aeSAndroid Build Coastguard Worker     combine_hash(seed, h(comparison.second));
110*9e3b08aeSAndroid Build Coastguard Worker     return seed;
111*9e3b08aeSAndroid Build Coastguard Worker   }
combine_hashHashComparison112*9e3b08aeSAndroid Build Coastguard Worker   static void combine_hash(size_t& seed, size_t hash) {
113*9e3b08aeSAndroid Build Coastguard Worker     seed ^= hash + 0x9e3779b97f4a7c15 + (seed << 12) + (seed >> 4);
114*9e3b08aeSAndroid Build Coastguard Worker   }
115*9e3b08aeSAndroid Build Coastguard Worker };
116*9e3b08aeSAndroid Build Coastguard Worker 
117*9e3b08aeSAndroid Build Coastguard Worker using Outcomes = std::unordered_map<Comparison, Diff, HashComparison>;
118*9e3b08aeSAndroid Build Coastguard Worker 
119*9e3b08aeSAndroid Build Coastguard Worker std::pair<Id, std::vector<std::string>> ResolveTypedefs(
120*9e3b08aeSAndroid Build Coastguard Worker     const Graph& graph, Id id);
121*9e3b08aeSAndroid Build Coastguard Worker 
122*9e3b08aeSAndroid Build Coastguard Worker Comparison Compare(Runtime& runtime, Ignore ignore, const Graph& graph,
123*9e3b08aeSAndroid Build Coastguard Worker                    Id root1, Id root2, Outcomes& outcomes);
124*9e3b08aeSAndroid Build Coastguard Worker 
125*9e3b08aeSAndroid Build Coastguard Worker }  // namespace diff
126*9e3b08aeSAndroid Build Coastguard Worker }  // namespace stg
127*9e3b08aeSAndroid Build Coastguard Worker 
128*9e3b08aeSAndroid Build Coastguard Worker #endif  // STG_COMPARISON_H_
129