13
13
#ifndef SWIFT_SIL_NOTIFICATIONS_H
14
14
#define SWIFT_SIL_NOTIFICATIONS_H
15
15
16
+ #include " swift/Basic/LLVM.h"
17
+ #include " swift/Basic/STLExtras.h"
18
+ #include " llvm/ADT/PointerUnion.h"
19
+ #include " llvm/ADT/SmallVector.h"
20
+ #include < memory>
21
+
16
22
namespace swift {
17
23
18
24
class SILNode ;
25
+ class ModuleDecl ;
26
+ class SILFunction ;
27
+ class SILWitnessTable ;
28
+ class SILDefaultWitnessTable ;
29
+ class SILGlobalVariable ;
30
+ class SILVTable ;
31
+
32
+ // / An abstract class for handling SIL deserialization notifications.
33
+ // /
34
+ // / This is an interface that should be implemented by clients that wish to
35
+ // / maintain a list of notification handlers. In contrast, handler
36
+ // / implementations should instead subclass DeserializationNotificationHandler
37
+ // / so that default no-op implementations can be inherited and so that it can be
38
+ // / passed into DeserializationNotificationHandlerSet.
39
+ class DeserializationNotificationHandlerBase {
40
+ public:
41
+ // / Observe that we deserialized a function declaration.
42
+ virtual void didDeserialize (ModuleDecl *mod, SILFunction *fn) = 0;
43
+
44
+ // / Observe that we successfully deserialized a function body.
45
+ virtual void didDeserializeFunctionBody (ModuleDecl *mod, SILFunction *fn) = 0;
46
+
47
+ // / Observe that we successfully deserialized a witness table's entries.
48
+ virtual void didDeserializeWitnessTableEntries (ModuleDecl *mod,
49
+ SILWitnessTable *wt) = 0;
50
+
51
+ // / Observe that we successfully deserialized a default witness table's
52
+ // / entries.
53
+ virtual void
54
+ didDeserializeDefaultWitnessTableEntries (ModuleDecl *mod,
55
+ SILDefaultWitnessTable *wt) = 0 ;
56
+
57
+ // / Observe that we deserialized a global variable declaration.
58
+ virtual void didDeserialize (ModuleDecl *mod, SILGlobalVariable *var) = 0;
59
+
60
+ // / Observe that we deserialized a v-table declaration.
61
+ virtual void didDeserialize (ModuleDecl *mod, SILVTable *vtable) = 0;
62
+
63
+ // / Observe that we deserialized a witness-table declaration.
64
+ virtual void didDeserialize (ModuleDecl *mod, SILWitnessTable *wtable) = 0;
65
+
66
+ // / Observe that we deserialized a default witness-table declaration.
67
+ virtual void didDeserialize (ModuleDecl *mod,
68
+ SILDefaultWitnessTable *wtable) = 0;
69
+
70
+ virtual ~DeserializationNotificationHandlerBase () = default ;
71
+ };
72
+
73
+ // / A no-op implementation of DeserializationNotificationHandlerBase. Intended
74
+ // / to allow for users to implement only one of the relevant methods and have
75
+ // / all other methods be no-ops.
76
+ class DeserializationNotificationHandler
77
+ : public DeserializationNotificationHandlerBase {
78
+ public:
79
+ // / Observe that we deserialized a function declaration.
80
+ virtual void didDeserialize (ModuleDecl *mod, SILFunction *fn) override {}
81
+
82
+ // / Observe that we successfully deserialized a function body.
83
+ virtual void didDeserializeFunctionBody (ModuleDecl *mod,
84
+ SILFunction *fn) override {}
85
+
86
+ // / Observe that we successfully deserialized a witness table's entries.
87
+ virtual void didDeserializeWitnessTableEntries (ModuleDecl *mod,
88
+ SILWitnessTable *wt) override {
89
+ }
90
+
91
+ // / Observe that we successfully deserialized a default witness table's
92
+ // / entries.
93
+ virtual void didDeserializeDefaultWitnessTableEntries (
94
+ ModuleDecl *mod, SILDefaultWitnessTable *wt) override {}
95
+
96
+ // / Observe that we deserialized a global variable declaration.
97
+ virtual void didDeserialize (ModuleDecl *mod,
98
+ SILGlobalVariable *var) override {}
99
+
100
+ // / Observe that we deserialized a v-table declaration.
101
+ virtual void didDeserialize (ModuleDecl *mod, SILVTable *vtable) override {}
102
+
103
+ // / Observe that we deserialized a witness-table declaration.
104
+ virtual void didDeserialize (ModuleDecl *mod,
105
+ SILWitnessTable *wtable) override {}
106
+
107
+ // / Observe that we deserialized a default witness-table declaration.
108
+ virtual void didDeserialize (ModuleDecl *mod,
109
+ SILDefaultWitnessTable *wtable) override {}
110
+
111
+ virtual StringRef getName () const = 0;
112
+
113
+ virtual ~DeserializationNotificationHandler () = default ;
114
+ };
115
+
116
+ // / A notification handler that only overrides didDeserializeFunctionBody and
117
+ // / calls the passed in function pointer.
118
+ class FunctionBodyDeserializationNotificationHandler final
119
+ : public DeserializationNotificationHandler {
120
+ public:
121
+ using Handler = void (*)(ModuleDecl *, SILFunction *);
122
+
123
+ private:
124
+ Handler handler;
125
+
126
+ public:
127
+ FunctionBodyDeserializationNotificationHandler (Handler handler)
128
+ : handler(handler) {}
129
+ virtual ~FunctionBodyDeserializationNotificationHandler () {}
130
+
131
+ void didDeserializeFunctionBody (ModuleDecl *mod, SILFunction *fn) override {
132
+ (*handler)(mod, fn);
133
+ }
134
+
135
+ StringRef getName () const override {
136
+ return " FunctionBodyDeserializationNotificationHandler" ;
137
+ }
138
+ };
139
+
140
+ // / A type that contains a set of unique DeserializationNotificationHandlers and
141
+ // / implements DeserializationNotificationHandlerBase by iterating over the
142
+ // / stored handlers and calling each handler's implementation.
143
+ class DeserializationNotificationHandlerSet final
144
+ : public DeserializationNotificationHandlerBase {
145
+ public:
146
+ using NotificationUniquePtr =
147
+ std::unique_ptr<DeserializationNotificationHandler>;
148
+
149
+ private:
150
+ // / A list of deserialization callbacks that update the SILModule and other
151
+ // / parts of SIL as deserialization occurs.
152
+ // /
153
+ // / We use 3 here since that is the most that will ever be used today in the
154
+ // / compiler. If that changed, that number should be changed as well. The
155
+ // / specific users are:
156
+ // /
157
+ // / 1. SILModule's serialization callback.
158
+ // / 2. SILPassManager notifications.
159
+ // / 3. Access Enforcement Stripping notification.
160
+ SmallVector<NotificationUniquePtr, 3 > handlerSet;
161
+
162
+ public:
163
+ DeserializationNotificationHandlerSet () = default ;
164
+ ~DeserializationNotificationHandlerSet () = default ;
165
+
166
+ bool erase (DeserializationNotificationHandler *handler) {
167
+ auto iter = find_if (handlerSet, [&](const NotificationUniquePtr &h) {
168
+ return handler == h.get ();
169
+ });
170
+ if (iter == handlerSet.end ())
171
+ return false ;
172
+ handlerSet.erase (iter);
173
+ return true ;
174
+ }
175
+
176
+ void add (NotificationUniquePtr &&handler) {
177
+ // Since we store unique_ptrs and are accepting a movable rvalue here, we
178
+ // should never have a case where we have a notification added twice. But
179
+ // just to be careful, lets use an assert.
180
+ assert (!count_if (handlerSet, [&](const NotificationUniquePtr &h) {
181
+ return handler.get () == h.get ();
182
+ }) && " Two unique ptrs pointing at the same memory?!" );
183
+ handlerSet.emplace_back (std::move (handler));
184
+ }
185
+
186
+ static DeserializationNotificationHandler *
187
+ getUnderlyingHandler (const NotificationUniquePtr &h) {
188
+ return h.get ();
189
+ }
190
+
191
+ // / An iterator into the notification set that returns a bare
192
+ // / 'DeserializationNotificationHandler *' projected from one of the
193
+ // / underlying std::unique_ptr<DeserializationNotificationHandler>.
194
+ using iterator = llvm::mapped_iterator<
195
+ decltype (handlerSet)::const_iterator,
196
+ decltype (&DeserializationNotificationHandlerSet::getUnderlyingHandler)>;
197
+ using range = llvm::iterator_range<iterator>;
198
+
199
+ // / Returns an iterator to the first element of the handler set.
200
+ // /
201
+ // / NOTE: This iterator has a value_type of
202
+ // / 'DeserializationNotificationHandler'.
203
+ iterator begin () const {
204
+ auto *fptr = &DeserializationNotificationHandlerSet::getUnderlyingHandler;
205
+ return llvm::map_iterator (handlerSet.begin (), fptr);
206
+ }
207
+
208
+ // / Returns an iterator to the end of the handler set.
209
+ // /
210
+ // / NOTE: This iterator has a value_type of
211
+ // / 'DeserializationNotificationHandler'.
212
+ iterator end () const {
213
+ auto *fptr = &DeserializationNotificationHandlerSet::getUnderlyingHandler;
214
+ return llvm::map_iterator (handlerSet.end (), fptr);
215
+ }
216
+
217
+ // / Returns a range that iterates over bare pointers projected from the
218
+ // / internal owned memory pointers in the handlerSet.
219
+ // /
220
+ // / NOTE: The underlying iterator value_type here is
221
+ // / 'DeserializationNotificationHandler *'.
222
+ auto getRange () const -> range { return llvm::make_range (begin (), end ()); }
223
+
224
+ // ===--------------------------------------------------------------------===//
225
+ // DeserializationNotificationHandler implementation via chaining to the
226
+ // handlers we contain.
227
+ // ===--------------------------------------------------------------------===//
228
+
229
+ void didDeserialize (ModuleDecl *mod, SILFunction *fn) override ;
230
+ void didDeserializeFunctionBody (ModuleDecl *mod, SILFunction *fn) override ;
231
+ void didDeserializeWitnessTableEntries (ModuleDecl *mod,
232
+ SILWitnessTable *wt) override ;
233
+ void
234
+ didDeserializeDefaultWitnessTableEntries (ModuleDecl *mod,
235
+ SILDefaultWitnessTable *wt) override ;
236
+ void didDeserialize (ModuleDecl *mod, SILGlobalVariable *var) override ;
237
+ void didDeserialize (ModuleDecl *mod, SILVTable *vtable) override ;
238
+ void didDeserialize (ModuleDecl *mod, SILWitnessTable *wtable) override ;
239
+ void didDeserialize (ModuleDecl *mod,
240
+ SILDefaultWitnessTable *wtable) override ;
241
+ };
19
242
20
243
// / A protocol (or interface) for handling value deletion notifications.
21
244
// /
@@ -24,7 +247,6 @@ class SILNode;
24
247
// / analysis that need to invalidate data structures that contain pointers.
25
248
// / This is similar to LLVM's ValueHandle.
26
249
struct DeleteNotificationHandler {
27
-
28
250
DeleteNotificationHandler () { }
29
251
virtual ~DeleteNotificationHandler () {}
30
252
@@ -38,7 +260,6 @@ struct DeleteNotificationHandler {
38
260
virtual bool needsNotifications () { return false ; }
39
261
};
40
262
41
- } // end swift namespace
263
+ } // namespace swift
42
264
43
265
#endif
44
-
0 commit comments