22
22
#ifndef SWIFT_REFLECTION_METADATASOURCE_H
23
23
#define SWIFT_REFLECTION_METADATASOURCE_H
24
24
25
+ #include " llvm/ADT/Optional.h"
25
26
#include " llvm/Support/Casting.h"
26
27
27
28
using llvm::cast;
@@ -39,6 +40,168 @@ enum class MetadataSourceKind {
39
40
40
41
class MetadataSource {
41
42
MetadataSourceKind Kind;
43
+
44
+ static bool decodeNatural (std::string::const_iterator &it,
45
+ const std::string::const_iterator &end,
46
+ unsigned &result) {
47
+ auto begin = it;
48
+ while (it != end) {
49
+ if (*it >= ' 0' && *it <= ' 9' )
50
+ ++it;
51
+ else
52
+ break ;
53
+ }
54
+
55
+ std::string natural (begin, it);
56
+ if (natural.empty ())
57
+ return false ;
58
+
59
+ result = std::stoi (natural);
60
+ return true ;
61
+ }
62
+
63
+ template <typename Allocator>
64
+ static const MetadataSource *
65
+ decodeClosureBinding (Allocator &A,
66
+ std::string::const_iterator &it,
67
+ const std::string::const_iterator &end) {
68
+ if (it == end)
69
+ return nullptr ;
70
+
71
+ if (*it == ' B' )
72
+ ++it;
73
+ else
74
+ return nullptr ;
75
+
76
+ unsigned Index;
77
+ if (!decodeNatural (it, end, Index))
78
+ return nullptr ;
79
+ return A.template createClosureBinding (Index);
80
+ }
81
+
82
+ template <typename Allocator>
83
+ static const MetadataSource *
84
+ decodeReferenceCapture (Allocator &A,
85
+ std::string::const_iterator &it,
86
+ const std::string::const_iterator &end) {
87
+ if (it == end)
88
+ return nullptr ;
89
+
90
+ if (*it == ' R' )
91
+ ++it;
92
+ else
93
+ return nullptr ;
94
+
95
+ unsigned Index;
96
+ if (!decodeNatural (it, end, Index))
97
+ return nullptr ;
98
+ return A.template createReferenceCapture (Index);
99
+ }
100
+
101
+ template <typename Allocator>
102
+ static const MetadataSource *
103
+ decodeMetadataCapture (Allocator &A,
104
+ std::string::const_iterator &it,
105
+ const std::string::const_iterator &end) {
106
+ if (it == end)
107
+ return nullptr ;
108
+
109
+ if (*it == ' M' )
110
+ ++it;
111
+ else
112
+ return nullptr ;
113
+
114
+ unsigned Index;
115
+ if (!decodeNatural (it, end, Index))
116
+ return nullptr ;
117
+ return A.template createMetadataCapture (Index);
118
+ }
119
+
120
+ template <typename Allocator>
121
+ static const MetadataSource *
122
+ decodeGenericArgument (Allocator &A,
123
+ std::string::const_iterator &it,
124
+ const std::string::const_iterator &end) {
125
+ if (it == end)
126
+ return nullptr ;
127
+
128
+ if (*it == ' G' )
129
+ ++it;
130
+ else
131
+ return nullptr ;
132
+
133
+ unsigned Index;
134
+ if (!decodeNatural (it, end, Index))
135
+ return nullptr ;
136
+
137
+ auto Source = decode (A, it, end);
138
+ if (!Source)
139
+ return nullptr ;
140
+
141
+ if (it == end || *it != ' _' )
142
+ return nullptr ;
143
+
144
+ ++it;
145
+
146
+ return A.template createGenericArgument (Index, Source);
147
+ }
148
+
149
+ template <typename Allocator>
150
+ static const MetadataSource*
151
+ decodeParent (Allocator &A,
152
+ std::string::const_iterator &it,
153
+ const std::string::const_iterator &end) {
154
+ if (it == end || *it != ' P' )
155
+ return nullptr ;
156
+
157
+ ++it;
158
+ auto Child = decode (A, it, end);
159
+ if (!Child)
160
+ return nullptr ;
161
+
162
+ if (it == end || *it != ' _' )
163
+ return nullptr ;
164
+
165
+ return A.template createParent (Child);
166
+ }
167
+
168
+ template <typename Allocator>
169
+ static const MetadataSource*
170
+ decodeImpossible (Allocator &A,
171
+ std::string::const_iterator &it,
172
+ const std::string::const_iterator &end) {
173
+ // Decode the impossible. Create the impossible.
174
+ if (it == end || *it != ' I' )
175
+ return nullptr ;
176
+
177
+ ++it;
178
+ return A.template createImpossible ();
179
+ }
180
+
181
+ template <typename Allocator>
182
+ static const MetadataSource *decode (Allocator &A,
183
+ std::string::const_iterator &it,
184
+ const std::string::const_iterator &end) {
185
+ if (it == end) return nullptr ;
186
+
187
+ switch (*it) {
188
+ case ' B' :
189
+ return decodeClosureBinding (A, it, end);
190
+ case ' R' :
191
+ return decodeReferenceCapture (A, it, end);
192
+ case ' M' :
193
+ return decodeMetadataCapture (A, it, end);
194
+ case ' G' :
195
+ return decodeGenericArgument (A, it, end);
196
+ case ' P' :
197
+ return decodeParent (A, it, end);
198
+ case ' I' :
199
+ return decodeImpossible (A, it, end);
200
+ default :
201
+ return nullptr ;
202
+ }
203
+ }
204
+
42
205
public:
43
206
MetadataSource (MetadataSourceKind Kind) : Kind(Kind) {}
44
207
@@ -48,6 +211,12 @@ class MetadataSource {
48
211
49
212
void dump () const ;
50
213
void dump (std::ostream &OS, unsigned Indent = 0 ) const ;
214
+ std::string encode () const ;
215
+ template <typename Allocator>
216
+ static const MetadataSource *decode (Allocator &A, const std::string &str) {
217
+ auto begin = str.begin ();
218
+ return MetadataSource::decode<Allocator>(A, begin, str.end ());
219
+ }
51
220
52
221
virtual ~MetadataSource () = default ;
53
222
};
@@ -59,8 +228,15 @@ class ClosureBindingMetadataSource final : public MetadataSource {
59
228
unsigned Index;
60
229
61
230
public:
62
- ClosureBindingMetadataSource (unsigned Index) :
63
- MetadataSource (MetadataSourceKind::ClosureBinding) {}
231
+
232
+ ClosureBindingMetadataSource (unsigned Index)
233
+ : MetadataSource(MetadataSourceKind::ClosureBinding), Index(Index) {}
234
+
235
+ template <typename Allocator>
236
+ static const ClosureBindingMetadataSource *
237
+ create (Allocator &A, unsigned Index) {
238
+ return A.template make_source <ClosureBindingMetadataSource>(Index);
239
+ }
64
240
65
241
unsigned getIndex () const {
66
242
return Index;
@@ -75,9 +251,16 @@ class ClosureBindingMetadataSource final : public MetadataSource {
75
251
// / be followed to the heap instance's data, then its metadata pointer.
76
252
class ReferenceCaptureMetadataSource final : public MetadataSource {
77
253
unsigned Index;
254
+
78
255
public:
79
- ReferenceCaptureMetadataSource (unsigned Index):
80
- MetadataSource (MetadataSourceKind::ReferenceCapture) {}
256
+ ReferenceCaptureMetadataSource (unsigned Index)
257
+ : MetadataSource(MetadataSourceKind::ReferenceCapture), Index(Index) {}
258
+
259
+ template <typename Allocator>
260
+ static const ReferenceCaptureMetadataSource *
261
+ create (Allocator &A, unsigned Index) {
262
+ return A.template make_source <ReferenceCaptureMetadataSource>(Index);
263
+ }
81
264
82
265
unsigned getIndex () const {
83
266
return Index;
@@ -88,6 +271,29 @@ class ReferenceCaptureMetadataSource final : public MetadataSource {
88
271
}
89
272
};
90
273
274
+ // / Represents a capture of a metadata pointer as an argument to a polymorphic function. These are direct sources of metadata.
275
+ class MetadataCaptureMetadataSource final : public MetadataSource {
276
+ unsigned Index;
277
+
278
+ public:
279
+ MetadataCaptureMetadataSource (unsigned Index)
280
+ : MetadataSource(MetadataSourceKind::MetadataCapture), Index(Index) {}
281
+
282
+ template <typename Allocator>
283
+ static const MetadataCaptureMetadataSource *
284
+ create (Allocator &A, unsigned Index) {
285
+ return A.template make_source <MetadataCaptureMetadataSource>(Index);
286
+ }
287
+
288
+ unsigned getIndex () const {
289
+ return Index;
290
+ }
291
+
292
+ static bool classof (const MetadataSource *MS) {
293
+ return MS->getKind () == MetadataSourceKind::MetadataCapture;
294
+ }
295
+ };
296
+
91
297
// / Represents the nth generic argument in some other source of instantiated
92
298
// / metadata.
93
299
// /
@@ -106,6 +312,12 @@ class GenericArgumentMetadataSource final : public MetadataSource {
106
312
Index (Index),
107
313
Source(Source) {}
108
314
315
+ template <typename Allocator>
316
+ static const GenericArgumentMetadataSource *
317
+ create (Allocator &A, unsigned Index, const MetadataSource *Source) {
318
+ return A.template make_source <GenericArgumentMetadataSource>(Index, Source);
319
+ }
320
+
109
321
unsigned getIndex () const {
110
322
return Index;
111
323
}
@@ -119,6 +331,37 @@ class GenericArgumentMetadataSource final : public MetadataSource {
119
331
}
120
332
};
121
333
334
+ class ParentMetadataSource final : public MetadataSource {
335
+ const MetadataSource *Child;
336
+ public:
337
+ ParentMetadataSource (const MetadataSource *Child)
338
+ : MetadataSource(MetadataSourceKind::Parent),
339
+ Child (Child) {}
340
+
341
+ template <typename Allocator>
342
+ static const ParentMetadataSource*
343
+ create (Allocator &A, const MetadataSource *Child) {
344
+ return A.template make_source <ParentMetadataSource>(Child);
345
+ }
346
+
347
+ const MetadataSource *getChild () const {
348
+ return Child;
349
+ }
350
+ };
351
+
352
+ class ImpossibleMetadataSource final : public MetadataSource {
353
+ static const ImpossibleMetadataSource *Singleton;
354
+ public:
355
+ ImpossibleMetadataSource ()
356
+ : MetadataSource(MetadataSourceKind::Impossible) {}
357
+
358
+ static const ImpossibleMetadataSource *get ();
359
+
360
+ static bool classof (const MetadataSource *MS) {
361
+ return MS->getKind () == MetadataSourceKind::Impossible;
362
+ }
363
+ };
364
+
122
365
template <typename ImplClass, typename RetTy = void , typename ... Args>
123
366
class MetadataSourceVisitor {
124
367
public:
0 commit comments