@@ -22,24 +22,50 @@ class TranslatorBase {
22
22
23
23
} // namespace detail
24
24
25
+ enum class TranslatorPolicy {
26
+ ignore,
27
+ translate,
28
+ translateParent,
29
+ emitUnknown,
30
+ };
31
+
25
32
// we want to override the default swift visitor behaviour of chaining calls to immediate
26
33
// superclasses by default and instead provide our own TBD default (using the exact type).
27
34
// Moreover, if the implementation class has translate##CLASS##KIND (that uses generated C++
28
35
// classes), for the class of for a parent thereof, we want to use that. We detect that by using the
29
36
// type traits HasTranslate##CLASS##KIND defined above.
30
37
// A special case is for explicitly ignored classes marked with void, which we should never
31
38
// 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
+ } \
43
69
}
44
70
45
71
// base class for our AST visitors, getting a SwiftDispatcher member and define_visit emission for
0 commit comments