xref: /aosp_15_r20/external/stg/substitution.h (revision 9e3b08ae94a55201065475453d799e8b1378bea6)
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