// 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 #include #include #include #include #include #include #include #include #include #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 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 ParseIgnore(std::string_view ignore); struct IgnoreUsage {}; std::ostream& operator<<(std::ostream& os, IgnoreUsage); using Comparison = std::pair, std::optional>; 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 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> 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; std::pair> 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_