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