| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // -*- mode: C++ -*- | |
| // | |
| // Copyright 2020-2024 Google LLC | |
| // | |
| // Licensed under the Apache License v2.0 with LLVM Exceptions (the | |
| // "License"); you may not use this file except in compliance with the | |
| // License. You may obtain a copy of the License at | |
| // | |
| // https://llvm.org/LICENSE.txt | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| // Author: Maria Teguiani | |
| // Author: Giuliano Procida | |
| // Author: Ignes Simeonova | |
| #ifndef STG_COMPARISON_H_ | |
| #define STG_COMPARISON_H_ | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <functional> | |
| #include <optional> | |
| #include <ostream> | |
| #include <string> | |
| #include <string_view> | |
| #include <unordered_map> | |
| #include <utility> | |
| #include <vector> | |
| #include "graph.h" | |
| #include "runtime.h" | |
| namespace stg { | |
| namespace diff { | |
| struct Ignore { | |
| enum Value { | |
| // noise reduction | |
| SYMBOL_TYPE_PRESENCE, | |
| TYPE_DECLARATION_STATUS, | |
| PRIMITIVE_TYPE_ENCODING, | |
| MEMBER_SIZE, | |
| ENUM_UNDERLYING_TYPE, | |
| QUALIFIER, | |
| SYMBOL_CRC, | |
| // ABI compatibility testing | |
| INTERFACE_ADDITION, | |
| TYPE_DEFINITION_ADDITION, | |
| }; | |
| using Bitset = uint16_t; | |
| Ignore() = default; | |
| template <typename... Values> | |
| explicit Ignore(Values... values) { | |
| for (auto value : {values...}) { | |
| Set(value); | |
| } | |
| } | |
| void Set(Value other) { | |
| bitset = bitset | (1 << other); | |
| } | |
| bool Test(Value other) const { | |
| return (bitset & (1 << other)) != 0; | |
| } | |
| Bitset bitset = 0; | |
| }; | |
| std::optional<Ignore::Value> ParseIgnore(std::string_view ignore); | |
| struct IgnoreUsage {}; | |
| std::ostream& operator<<(std::ostream& os, IgnoreUsage); | |
| using Comparison = std::pair<std::optional<Id>, std::optional<Id>>; | |
| struct DiffDetail { | |
| DiffDetail(const std::string& text, const Comparison& edge) | |
| : text(text), edge(edge) {} | |
| std::string text; | |
| Comparison edge; | |
| }; | |
| struct Diff { | |
| // This diff node corresponds to an entity that is reportable, if it or any of | |
| // its children (excluding reportable ones) has changed. | |
| bool holds_changes = false; | |
| // This diff node contains a local (non-recursive) change. | |
| bool has_changes = false; | |
| std::vector<DiffDetail> details; | |
| void Add(const std::string& text, const Comparison& comparison) { | |
| details.emplace_back(text, comparison); | |
| } | |
| }; | |
| struct HashComparison { | |
| size_t operator()(const Comparison& comparison) const { | |
| size_t seed = 0; | |
| const std::hash<std::optional<Id>> h; | |
| combine_hash(seed, h(comparison.first)); | |
| combine_hash(seed, h(comparison.second)); | |
| return seed; | |
| } | |
| static void combine_hash(size_t& seed, size_t hash) { | |
| seed ^= hash + 0x9e3779b97f4a7c15 + (seed << 12) + (seed >> 4); | |
| } | |
| }; | |
| using Outcomes = std::unordered_map<Comparison, Diff, HashComparison>; | |
| std::pair<Id, std::vector<std::string>> ResolveTypedefs( | |
| const Graph& graph, Id id); | |
| Comparison Compare(Runtime& runtime, Ignore ignore, const Graph& graph, | |
| Id root1, Id root2, Outcomes& outcomes); | |
| } // namespace diff | |
| } // namespace stg | |
| #endif // STG_COMPARISON_H_ |