@@ -22,24 +22,50 @@ class TranslatorBase {
2222
2323} // namespace detail
2424
25+ enum class TranslatorPolicy {
26+ ignore,
27+ translate,
28+ translateParent,
29+ emitUnknown,
30+ };
31+
2532// we want to override the default swift visitor behaviour of chaining calls to immediate
2633// superclasses by default and instead provide our own TBD default (using the exact type).
2734// Moreover, if the implementation class has translate##CLASS##KIND (that uses generated C++
2835// classes), for the class of for a parent thereof, we want to use that. We detect that by using the
2936// type traits HasTranslate##CLASS##KIND defined above.
3037// A special case is for explicitly ignored classes marked with void, which we should never
3138// encounter.
32- #define DEFINE_VISIT (KIND, CLASS, PARENT ) \
33- void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
34- if constexpr (std::same_as<TrapTagOf<swift::CLASS##KIND>, void >) { \
35- LOG_ERROR (" Unexpected " #CLASS #KIND); \
36- } else if constexpr (requires (CrtpSubclass x) { x.translate ##CLASS##KIND (*e); }) { \
37- dispatcher.emit (static_cast <CrtpSubclass*>(this )->translate ##CLASS##KIND (*e)); \
38- } else if constexpr (requires (CrtpSubclass x) { x.translate ##PARENT (*e); }) { \
39- dispatcher.emit (static_cast <CrtpSubclass*>(this )->translate ##PARENT (*e)); \
40- } else { \
41- dispatcher.emitUnknown (e); \
42- } \
39+ #define DEFINE_VISIT (KIND, CLASS, PARENT ) \
40+ public: \
41+ static constexpr TranslatorPolicy getPolicyFor##CLASS##KIND() { \
42+ if constexpr (std::same_as<TrapTagOf<swift::CLASS##KIND>, void >) { \
43+ return TranslatorPolicy::ignore; \
44+ } else if constexpr (requires (CrtpSubclass x, swift::CLASS##KIND e) { \
45+ x.translate ##CLASS##KIND (e); \
46+ }) { \
47+ return TranslatorPolicy::translate; \
48+ } else if constexpr (requires (CrtpSubclass x, swift::CLASS##KIND e) { \
49+ x.translate ##PARENT (e); \
50+ }) { \
51+ return TranslatorPolicy::translateParent; \
52+ } else { \
53+ return TranslatorPolicy::emitUnknown; \
54+ } \
55+ } \
56+ \
57+ private: \
58+ void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
59+ constexpr auto policy = getPolicyFor##CLASS##KIND (); \
60+ if constexpr (policy == TranslatorPolicy::ignore) { \
61+ LOG_ERROR (" Unexpected " #CLASS #KIND); \
62+ } else if constexpr (policy == TranslatorPolicy::translate) { \
63+ dispatcher.emit (static_cast <CrtpSubclass*>(this )->translate ##CLASS##KIND (*e)); \
64+ } else if constexpr (policy == TranslatorPolicy::translateParent) { \
65+ dispatcher.emit (static_cast <CrtpSubclass*>(this )->translate ##PARENT (*e)); \
66+ } else if constexpr (policy == TranslatorPolicy::emitUnknown) { \
67+ dispatcher.emitUnknown (e); \
68+ } \
4369 }
4470
4571// base class for our AST visitors, getting a SwiftDispatcher member and define_visit emission for
0 commit comments