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,156 @@ 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 *decode (Allocator &A,
170
+ std::string::const_iterator &it,
171
+ const std::string::const_iterator &end) {
172
+ if (it == end) return nullptr ;
173
+
174
+ switch (*it) {
175
+ case ' B' :
176
+ return decodeClosureBinding (A, it, end);
177
+ case ' R' :
178
+ return decodeReferenceCapture (A, it, end);
179
+ case ' M' :
180
+ return decodeMetadataCapture (A, it, end);
181
+ case ' G' :
182
+ return decodeGenericArgument (A, it, end);
183
+ case ' P' :
184
+ return decodeParent (A, it, end);
185
+ case ' S' :
186
+ ++it;
187
+ return A.template createSelf ();
188
+ default :
189
+ return nullptr ;
190
+ }
191
+ }
192
+
42
193
public:
43
194
MetadataSource (MetadataSourceKind Kind) : Kind(Kind) {}
44
195
@@ -48,6 +199,11 @@ class MetadataSource {
48
199
49
200
void dump () const ;
50
201
void dump (std::ostream &OS, unsigned Indent = 0 ) const ;
202
+ template <typename Allocator>
203
+ static const MetadataSource *decode (Allocator &A, const std::string &str) {
204
+ auto begin = str.begin ();
205
+ return MetadataSource::decode<Allocator>(A, begin, str.end ());
206
+ }
51
207
52
208
virtual ~MetadataSource () = default ;
53
209
};
@@ -59,8 +215,15 @@ class ClosureBindingMetadataSource final : public MetadataSource {
59
215
unsigned Index;
60
216
61
217
public:
62
- ClosureBindingMetadataSource (unsigned Index) :
63
- MetadataSource (MetadataSourceKind::ClosureBinding) {}
218
+
219
+ ClosureBindingMetadataSource (unsigned Index)
220
+ : MetadataSource(MetadataSourceKind::ClosureBinding), Index(Index) {}
221
+
222
+ template <typename Allocator>
223
+ static const ClosureBindingMetadataSource *
224
+ create (Allocator &A, unsigned Index) {
225
+ return A.template make_source <ClosureBindingMetadataSource>(Index);
226
+ }
64
227
65
228
unsigned getIndex () const {
66
229
return Index;
@@ -75,9 +238,16 @@ class ClosureBindingMetadataSource final : public MetadataSource {
75
238
// / be followed to the heap instance's data, then its metadata pointer.
76
239
class ReferenceCaptureMetadataSource final : public MetadataSource {
77
240
unsigned Index;
241
+
78
242
public:
79
- ReferenceCaptureMetadataSource (unsigned Index):
80
- MetadataSource (MetadataSourceKind::ReferenceCapture) {}
243
+ ReferenceCaptureMetadataSource (unsigned Index)
244
+ : MetadataSource(MetadataSourceKind::ReferenceCapture), Index(Index) {}
245
+
246
+ template <typename Allocator>
247
+ static const ReferenceCaptureMetadataSource *
248
+ create (Allocator &A, unsigned Index) {
249
+ return A.template make_source <ReferenceCaptureMetadataSource>(Index);
250
+ }
81
251
82
252
unsigned getIndex () const {
83
253
return Index;
@@ -88,6 +258,29 @@ class ReferenceCaptureMetadataSource final : public MetadataSource {
88
258
}
89
259
};
90
260
261
+ // / Represents a capture of a metadata pointer as an argument to a polymorphic function. These are direct sources of metadata.
262
+ class MetadataCaptureMetadataSource final : public MetadataSource {
263
+ unsigned Index;
264
+
265
+ public:
266
+ MetadataCaptureMetadataSource (unsigned Index)
267
+ : MetadataSource(MetadataSourceKind::MetadataCapture), Index(Index) {}
268
+
269
+ template <typename Allocator>
270
+ static const MetadataCaptureMetadataSource *
271
+ create (Allocator &A, unsigned Index) {
272
+ return A.template make_source <MetadataCaptureMetadataSource>(Index);
273
+ }
274
+
275
+ unsigned getIndex () const {
276
+ return Index;
277
+ }
278
+
279
+ static bool classof (const MetadataSource *MS) {
280
+ return MS->getKind () == MetadataSourceKind::MetadataCapture;
281
+ }
282
+ };
283
+
91
284
// / Represents the nth generic argument in some other source of instantiated
92
285
// / metadata.
93
286
// /
@@ -106,6 +299,12 @@ class GenericArgumentMetadataSource final : public MetadataSource {
106
299
Index (Index),
107
300
Source(Source) {}
108
301
302
+ template <typename Allocator>
303
+ static const GenericArgumentMetadataSource *
304
+ create (Allocator &A, unsigned Index, const MetadataSource *Source) {
305
+ return A.template make_source <GenericArgumentMetadataSource>(Index, Source);
306
+ }
307
+
109
308
unsigned getIndex () const {
110
309
return Index;
111
310
}
@@ -119,6 +318,64 @@ class GenericArgumentMetadataSource final : public MetadataSource {
119
318
}
120
319
};
121
320
321
+ // / Metadata gotten through the parent of a nominal type's metadata.
322
+ class ParentMetadataSource final : public MetadataSource {
323
+ const MetadataSource *Child;
324
+ public:
325
+ ParentMetadataSource (const MetadataSource *Child)
326
+ : MetadataSource(MetadataSourceKind::Parent),
327
+ Child (Child) {}
328
+
329
+ template <typename Allocator>
330
+ static const ParentMetadataSource*
331
+ create (Allocator &A, const MetadataSource *Child) {
332
+ return A.template make_source <ParentMetadataSource>(Child);
333
+ }
334
+
335
+ const MetadataSource *getChild () const {
336
+ return Child;
337
+ }
338
+
339
+ static bool classof (const MetadataSource *MS) {
340
+ return MS->getKind () == MetadataSourceKind::Parent;
341
+ }
342
+ };
343
+
344
+ // / A source of metadata from the Self metadata parameter passed via
345
+ // / a witness_method convention function.
346
+ class SelfMetadataSource final : public MetadataSource {
347
+ public:
348
+ SelfMetadataSource () : MetadataSource(MetadataSourceKind::Self) {}
349
+
350
+ template <typename Allocator>
351
+ static const SelfMetadataSource*
352
+ create (Allocator &A) {
353
+ return A.template make_source <SelfMetadataSource>();
354
+ }
355
+
356
+ static bool classof (const MetadataSource *MS) {
357
+ return MS->getKind () == MetadataSourceKind::Self;
358
+ }
359
+ };
360
+
361
+ // / A source of metadata from the Self witness table parameter passed via
362
+ // / a witness_method convention function.
363
+ class SelfWitnessTableMetadataSource final : public MetadataSource {
364
+ public:
365
+ SelfWitnessTableMetadataSource ()
366
+ : MetadataSource(MetadataSourceKind::SelfWitnessTable) {}
367
+
368
+ template <typename Allocator>
369
+ static const SelfWitnessTableMetadataSource*
370
+ create (Allocator &A) {
371
+ return A.template make_source <SelfWitnessTableMetadataSource>();
372
+ }
373
+
374
+ static bool classof (const MetadataSource *MS) {
375
+ return MS->getKind () == MetadataSourceKind::SelfWitnessTable;
376
+ }
377
+ };
378
+
122
379
template <typename ImplClass, typename RetTy = void , typename ... Args>
123
380
class MetadataSourceVisitor {
124
381
public:
0 commit comments