@@ -38,19 +38,6 @@ class SwiftDispatcher {
38
38
const swift::PoundAvailableInfo*,
39
39
const swift::AvailabilitySpec*>;
40
40
41
- template <typename E>
42
- static constexpr bool IsFetchable = std::is_constructible_v<Handle , const E&>;
43
-
44
- template <typename E>
45
- static constexpr bool IsLocatable =
46
- std::is_base_of_v<LocatableTag, TrapTagOf<E>> && !std::is_base_of_v<TypeTag, TrapTagOf<E>>;
47
-
48
- template <typename E>
49
- static constexpr bool IsDeclPointer = std::is_convertible_v<E, const swift::Decl*>;
50
-
51
- template <typename E>
52
- static constexpr bool IsTypePointer = std::is_convertible_v<E, const swift::TypeBase*>;
53
-
54
41
public:
55
42
// all references and pointers passed as parameters to this constructor are supposed to outlive
56
43
// the SwiftDispatcher
@@ -76,7 +63,7 @@ class SwiftDispatcher {
76
63
using Label = std::remove_reference_t <decltype (label)>;
77
64
if (!label.valid ()) {
78
65
const char * action;
79
- if constexpr (std::is_base_of_v< typename Label::Tag, UnspecifiedElementTag >) {
66
+ if constexpr (std::derived_from<UnspecifiedElementTag, typename Label::Tag>) {
80
67
action = " replacing with unspecified element" ;
81
68
label = emitUnspecified (idOf (entry), field, index );
82
69
} else {
@@ -132,7 +119,7 @@ class SwiftDispatcher {
132
119
133
120
template <typename E>
134
121
std::optional<TrapLabel<ElementTag>> idOf (const E& entry) {
135
- if constexpr (HasId<E>::value ) {
122
+ if constexpr (requires { entry. id ; } ) {
136
123
return entry.id ;
137
124
} else {
138
125
return std::nullopt;
@@ -142,13 +129,14 @@ class SwiftDispatcher {
142
129
// This method gives a TRAP label for already emitted AST node.
143
130
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
144
131
// visitor (see `visit(T *)` methods below).
145
- template <typename E, std::enable_if_t <IsFetchable<E>>* = nullptr >
146
- TrapLabelOf<E> fetchLabel (const E& e, swift::Type type = {}) {
147
- if constexpr (std::is_constructible_v<bool , const E&>) {
148
- if (!e) {
149
- // this will be treated on emission
150
- return undefined_label;
151
- }
132
+ // clang-format off
133
+ template <typename E>
134
+ requires std::constructible_from<Handle , E*>
135
+ TrapLabelOf<E> fetchLabel (const E* e, swift::Type type = {}) {
136
+ // clang-format on
137
+ if (!e) {
138
+ // this will be treated on emission
139
+ return undefined_label;
152
140
}
153
141
auto & stored = store[e];
154
142
if (!stored.valid ()) {
@@ -174,8 +162,11 @@ class SwiftDispatcher {
174
162
return ret;
175
163
}
176
164
177
- template <typename E, std::enable_if_t <IsFetchable<E*>>* = nullptr >
165
+ // clang-format off
166
+ template <typename E>
167
+ requires std::constructible_from<Handle , E*>
178
168
TrapLabelOf<E> fetchLabel (const E& e) {
169
+ // clang-format on
179
170
return fetchLabel (&e);
180
171
}
181
172
@@ -184,7 +175,8 @@ class SwiftDispatcher {
184
175
auto createEntry (const E& e) {
185
176
auto found = store.find (&e);
186
177
CODEQL_ASSERT (found != store.end (), " createEntry called on non-fetched label" );
187
- auto label = TrapLabel<ConcreteTrapTagOf<E>>::unsafeCreateFromUntyped (found->second );
178
+ using Tag = ConcreteTrapTagOf<E>;
179
+ auto label = TrapLabel<Tag>::unsafeCreateFromUntyped (found->second );
188
180
if constexpr (IsLocatable<E>) {
189
181
locationExtractor.attachLocation (sourceManager, e, label);
190
182
}
@@ -195,7 +187,8 @@ class SwiftDispatcher {
195
187
// an example is swift::Argument, that are created on the fly and thus have no stable pointer
196
188
template <typename E>
197
189
auto createUncachedEntry (const E& e) {
198
- auto label = trap.createTypedLabel <TrapTagOf<E>>();
190
+ using Tag = TrapTagOf<E>;
191
+ auto label = trap.createTypedLabel <Tag>();
199
192
locationExtractor.attachLocation (sourceManager, &e, label);
200
193
return TrapClassOf<E>{label};
201
194
}
@@ -218,7 +211,7 @@ class SwiftDispatcher {
218
211
auto fetchRepeatedLabels (Iterable&& arg) {
219
212
using Label = decltype (fetchLabel (*arg.begin ()));
220
213
TrapLabelVectorWrapper<typename Label::Tag> ret;
221
- if constexpr (HasSize<Iterable>::value ) {
214
+ if constexpr (requires { arg. size (); } ) {
222
215
ret.data .reserve (arg.size ());
223
216
}
224
217
for (auto && e : arg) {
@@ -251,7 +244,7 @@ class SwiftDispatcher {
251
244
private:
252
245
template <typename E>
253
246
UntypedTrapLabel createLabel (const E& e, swift::Type type) {
254
- if constexpr (IsDeclPointer<E> || IsTypePointer<E> ) {
247
+ if constexpr (requires { name (e); } ) {
255
248
if (auto mangledName = name (e)) {
256
249
if (shouldVisit (e)) {
257
250
toBeVisited.emplace_back (e, type);
@@ -266,7 +259,7 @@ class SwiftDispatcher {
266
259
267
260
template <typename E>
268
261
bool shouldVisit (const E& e) {
269
- if constexpr (IsDeclPointer<E >) {
262
+ if constexpr (std::convertible_to<E, const swift::Decl* >) {
270
263
encounteredModules.insert (e->getModuleContext ());
271
264
if (bodyEmissionStrategy.shouldEmitDeclBody (*e)) {
272
265
extractedDeclaration (e);
@@ -295,18 +288,6 @@ class SwiftDispatcher {
295
288
module->isNonSwiftModule ();
296
289
}
297
290
298
- template <typename T, typename = void >
299
- struct HasSize : std::false_type {};
300
-
301
- template <typename T>
302
- struct HasSize <T, decltype(std::declval<T>().size(), void ())> : std::true_type {};
303
-
304
- template <typename T, typename = void >
305
- struct HasId : std::false_type {};
306
-
307
- template <typename T>
308
- struct HasId <T, decltype(std::declval<T>().id, void ())> : std::true_type {};
309
-
310
291
template <typename Tag, typename ... Ts>
311
292
TrapLabel<Tag> fetchLabelFromUnion (const llvm::PointerUnion<Ts...> u) {
312
293
TrapLabel<Tag> ret{};
@@ -324,7 +305,7 @@ class SwiftDispatcher {
324
305
// on `BraceStmt`/`IfConfigDecl` elements), we cannot encounter a standalone `TypeRepr` there,
325
306
// so we skip this case; extracting `TypeRepr`s here would be problematic as we would not be
326
307
// able to provide the corresponding type
327
- if constexpr (!std::is_same_v <T, swift::TypeRepr*>) {
308
+ if constexpr (!std::same_as <T, swift::TypeRepr*>) {
328
309
if (auto e = u.template dyn_cast <T>()) {
329
310
output = fetchLabel (e);
330
311
return true ;
@@ -348,10 +329,8 @@ class SwiftDispatcher {
348
329
virtual void visit (const swift::TypeBase* type) = 0;
349
330
virtual void visit (const swift::CapturedValue* capture) = 0;
350
331
351
- template <typename T, std::enable_if<!std::is_base_of_v<swift::TypeRepr, T>>* = nullptr >
352
- void visit (const T* e, swift::Type) {
353
- visit (e);
354
- }
332
+ template <typename T>
333
+ requires (!std::derived_from<T, swift::TypeRepr>) void visit (const T* e, swift::Type) { visit (e); }
355
334
356
335
const swift::SourceManager& sourceManager;
357
336
SwiftExtractorState& state;
0 commit comments