| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // -*- mode: C++ -*- |
| // |
| // Copyright 2022 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: Giuliano Procida |
| |
| #ifndef STG_SUBSTITUTION_H_ |
| #define STG_SUBSTITUTION_H_ |
| |
| #include <map> |
| #include <vector> |
| |
| #include "graph.h" |
| |
| namespace stg { |
| |
| // This is a single-node node id substitution function that updates all node |
| // references according to a given mapping. The caller is responsible for |
| // determining the nodes to which substitution should apply (e.g., excluding |
| // orphaned nodes). |
| // |
| // The caller must provide a reference to a callable object which should update |
| // its Id argument only when needed (i.e., when the new value is different). |
| // |
| // The Update helpers may be used to update external node id references. |
| template <typename Updater> |
| struct Substitute { |
| Substitute(Graph& graph, const Updater& updater) |
| : graph(graph), updater(updater) {} |
| |
| void Update(Id& id) const { |
| updater(id); |
| } |
| |
| void Update(std::vector<Id>& ids) const { |
| for (auto& id : ids) { |
| Update(id); |
| } |
| } |
| |
| template <typename Key> |
| void Update(std::map<Key, Id>& ids) const { |
| for (auto& [key, id] : ids) { |
| Update(id); |
| } |
| } |
| |
| void operator()(Id id) { |
| return graph.Apply<void>(*this, id); |
| } |
| |
| void operator()(Special&) {} |
| |
| void operator()(PointerReference& x) { |
| Update(x.pointee_type_id); |
| } |
| |
| void operator()(PointerToMember& x) { |
| Update(x.containing_type_id); |
| Update(x.pointee_type_id); |
| } |
| |
| void operator()(Typedef& x) { |
| Update(x.referred_type_id); |
| } |
| |
| void operator()(Qualified& x) { |
| Update(x.qualified_type_id); |
| } |
| |
| void operator()(Primitive&) {} |
| |
| void operator()(Array& x) { |
| Update(x.element_type_id); |
| } |
| |
| void operator()(BaseClass& x) { |
| Update(x.type_id); |
| } |
| |
| void operator()(Member& x) { |
| Update(x.type_id); |
| } |
| |
| void operator()(Method& x) { |
| Update(x.type_id); |
| } |
| |
| void operator()(StructUnion& x) { |
| if (x.definition.has_value()) { |
| auto& definition = x.definition.value(); |
| Update(definition.base_classes); |
| Update(definition.methods); |
| Update(definition.members); |
| } |
| } |
| |
| void operator()(Enumeration& x) { |
| if (x.definition.has_value()) { |
| auto& definition = x.definition.value(); |
| Update(definition.underlying_type_id); |
| } |
| } |
| |
| void operator()(Function& x) { |
| Update(x.parameters); |
| Update(x.return_type_id); |
| } |
| |
| void operator()(ElfSymbol& x) { |
| if (x.type_id) { |
| Update(*x.type_id); |
| } |
| } |
| |
| void operator()(Interface& x) { |
| Update(x.symbols); |
| Update(x.types); |
| } |
| |
| Graph& graph; |
| const Updater& updater; |
| }; |
| |
| template <class Updater> |
| Substitute(Graph&, const Updater& updater) -> Substitute<decltype(updater)>; |
| |
| } // namespace stg |
| |
| #endif // STG_SUBSTITUTION_H_ |