1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- mode: C++ -*- 3 // 4 // Copyright 2022-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: Giuliano Procida 19 20 #ifndef STG_SUBSTITUTION_H_ 21 #define STG_SUBSTITUTION_H_ 22 23 #include <map> 24 #include <vector> 25 26 #include "graph.h" 27 28 namespace stg { 29 30 // This is a single-node node id substitution function that updates all node 31 // references according to a given mapping. The caller is responsible for 32 // determining the nodes to which substitution should apply (e.g., excluding 33 // orphaned nodes). 34 // 35 // The caller must provide a reference to a callable object which should update 36 // its Id argument only when needed (i.e., when the new value is different). 37 // 38 // The Update helpers may be used to update external node id references. 39 template <typename Updater> 40 struct Substitute { SubstituteSubstitute41 Substitute(Graph& graph, const Updater& updater) 42 : graph(graph), updater(updater) {} 43 UpdateSubstitute44 void Update(Id& id) const { 45 updater(id); 46 } 47 UpdateSubstitute48 void Update(std::vector<Id>& ids) const { 49 for (auto& id : ids) { 50 Update(id); 51 } 52 } 53 54 template <typename Key> UpdateSubstitute55 void Update(std::map<Key, Id>& ids) const { 56 for (auto& [key, id] : ids) { 57 Update(id); 58 } 59 } 60 operatorSubstitute61 void operator()(Id id) const { 62 return graph.Apply(*this, id); 63 } 64 operatorSubstitute65 void operator()(Special&) const {} 66 operatorSubstitute67 void operator()(PointerReference& x) const { 68 Update(x.pointee_type_id); 69 } 70 operatorSubstitute71 void operator()(PointerToMember& x) const { 72 Update(x.containing_type_id); 73 Update(x.pointee_type_id); 74 } 75 operatorSubstitute76 void operator()(Typedef& x) const { 77 Update(x.referred_type_id); 78 } 79 operatorSubstitute80 void operator()(Qualified& x) const { 81 Update(x.qualified_type_id); 82 } 83 operatorSubstitute84 void operator()(Primitive&) const {} 85 operatorSubstitute86 void operator()(Array& x) const { 87 Update(x.element_type_id); 88 } 89 operatorSubstitute90 void operator()(BaseClass& x) const { 91 Update(x.type_id); 92 } 93 operatorSubstitute94 void operator()(Method& x) const { 95 Update(x.type_id); 96 } 97 operatorSubstitute98 void operator()(Member& x) const { 99 Update(x.type_id); 100 } 101 operatorSubstitute102 void operator()(VariantMember& x) const { 103 Update(x.type_id); 104 } 105 operatorSubstitute106 void operator()(StructUnion& x) const { 107 if (x.definition.has_value()) { 108 auto& definition = x.definition.value(); 109 Update(definition.base_classes); 110 Update(definition.methods); 111 Update(definition.members); 112 } 113 } 114 operatorSubstitute115 void operator()(Enumeration& x) const { 116 if (x.definition.has_value()) { 117 auto& definition = x.definition.value(); 118 Update(definition.underlying_type_id); 119 } 120 } 121 operatorSubstitute122 void operator()(Variant& x) const { 123 if (x.discriminant.has_value()) { 124 Update(x.discriminant.value()); 125 } 126 Update(x.members); 127 } 128 operatorSubstitute129 void operator()(Function& x) const { 130 Update(x.parameters); 131 Update(x.return_type_id); 132 } 133 operatorSubstitute134 void operator()(ElfSymbol& x) const { 135 if (x.type_id) { 136 Update(*x.type_id); 137 } 138 } 139 operatorSubstitute140 void operator()(Interface& x) const { 141 Update(x.symbols); 142 Update(x.types); 143 } 144 145 Graph& graph; 146 const Updater& updater; 147 }; 148 149 template <class Updater> 150 Substitute(Graph&, const Updater& updater) -> Substitute<decltype(updater)>; 151 152 } // namespace stg 153 154 #endif // STG_SUBSTITUTION_H_ 155