@@ -38,19 +38,6 @@ class SwiftDispatcher {
3838 const swift::PoundAvailableInfo*,
3939 const swift::AvailabilitySpec*>;
4040
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-
5441 public:
5542 // all references and pointers passed as parameters to this constructor are supposed to outlive
5643 // the SwiftDispatcher
@@ -76,7 +63,7 @@ class SwiftDispatcher {
7663 using Label = std::remove_reference_t <decltype (label)>;
7764 if (!label.valid ()) {
7865 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>) {
8067 action = " replacing with unspecified element" ;
8168 label = emitUnspecified (idOf (entry), field, index);
8269 } else {
@@ -132,7 +119,7 @@ class SwiftDispatcher {
132119
133120 template <typename E>
134121 std::optional<TrapLabel<ElementTag>> idOf (const E& entry) {
135- if constexpr (HasId<E>::value ) {
122+ if constexpr (requires { entry. id ; } ) {
136123 return entry.id ;
137124 } else {
138125 return std::nullopt ;
@@ -142,13 +129,14 @@ class SwiftDispatcher {
142129 // This method gives a TRAP label for already emitted AST node.
143130 // If the AST node was not emitted yet, then the emission is dispatched to a corresponding
144131 // 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;
152140 }
153141 auto & stored = store[e];
154142 if (!stored.valid ()) {
@@ -174,8 +162,11 @@ class SwiftDispatcher {
174162 return ret;
175163 }
176164
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*>
178168 TrapLabelOf<E> fetchLabel (const E& e) {
169+ // clang-format on
179170 return fetchLabel (&e);
180171 }
181172
@@ -184,7 +175,8 @@ class SwiftDispatcher {
184175 auto createEntry (const E& e) {
185176 auto found = store.find (&e);
186177 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 );
188180 if constexpr (IsLocatable<E>) {
189181 locationExtractor.attachLocation (sourceManager, e, label);
190182 }
@@ -195,7 +187,8 @@ class SwiftDispatcher {
195187 // an example is swift::Argument, that are created on the fly and thus have no stable pointer
196188 template <typename E>
197189 auto createUncachedEntry (const E& e) {
198- auto label = trap.createTypedLabel <TrapTagOf<E>>();
190+ using Tag = TrapTagOf<E>;
191+ auto label = trap.createTypedLabel <Tag>();
199192 locationExtractor.attachLocation (sourceManager, &e, label);
200193 return TrapClassOf<E>{label};
201194 }
@@ -218,7 +211,7 @@ class SwiftDispatcher {
218211 auto fetchRepeatedLabels (Iterable&& arg) {
219212 using Label = decltype (fetchLabel (*arg.begin ()));
220213 TrapLabelVectorWrapper<typename Label::Tag> ret;
221- if constexpr (HasSize<Iterable>::value ) {
214+ if constexpr (requires { arg. size (); } ) {
222215 ret.data .reserve (arg.size ());
223216 }
224217 for (auto && e : arg) {
@@ -251,7 +244,7 @@ class SwiftDispatcher {
251244 private:
252245 template <typename E>
253246 UntypedTrapLabel createLabel (const E& e, swift::Type type) {
254- if constexpr (IsDeclPointer<E> || IsTypePointer<E> ) {
247+ if constexpr (requires { name (e); } ) {
255248 if (auto mangledName = name (e)) {
256249 if (shouldVisit (e)) {
257250 toBeVisited.emplace_back (e, type);
@@ -266,7 +259,7 @@ class SwiftDispatcher {
266259
267260 template <typename E>
268261 bool shouldVisit (const E& e) {
269- if constexpr (IsDeclPointer<E >) {
262+ if constexpr (std::convertible_to<E, const swift::Decl* >) {
270263 encounteredModules.insert (e->getModuleContext ());
271264 if (bodyEmissionStrategy.shouldEmitDeclBody (*e)) {
272265 extractedDeclaration (e);
@@ -295,18 +288,6 @@ class SwiftDispatcher {
295288 module ->isNonSwiftModule ();
296289 }
297290
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-
310291 template <typename Tag, typename ... Ts>
311292 TrapLabel<Tag> fetchLabelFromUnion (const llvm::PointerUnion<Ts...> u) {
312293 TrapLabel<Tag> ret{};
@@ -324,7 +305,7 @@ class SwiftDispatcher {
324305 // on `BraceStmt`/`IfConfigDecl` elements), we cannot encounter a standalone `TypeRepr` there,
325306 // so we skip this case; extracting `TypeRepr`s here would be problematic as we would not be
326307 // 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*>) {
328309 if (auto e = u.template dyn_cast <T>()) {
329310 output = fetchLabel (e);
330311 return true ;
@@ -348,10 +329,8 @@ class SwiftDispatcher {
348329 virtual void visit (const swift::TypeBase* type) = 0;
349330 virtual void visit (const swift::CapturedValue* capture) = 0;
350331
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); }
355334
356335 const swift::SourceManager& sourceManager;
357336 SwiftExtractorState& state;
0 commit comments