Swift: change translation signature and detection

Translation now takes const references to swift entities and return
trap entries (instead of taking apointer as an out parameter).
This commit is contained in:
Paolo Tranquilli
2022-05-31 11:07:58 +02:00
parent c3cb0d6ad7
commit 19f16678ac
4 changed files with 151 additions and 135 deletions

View File

@@ -20,35 +20,32 @@ class VisitorBase {
} // namespace detail
// we want to override the default swift visitor behaviour of chaining calls to immediate
// superclasses by default and instead provide our own TBD default (using the exact type)
// if we the implementation class has translate##CLASS##KIND (that uses generated C++ classes), we
// want to use that. We detect that by comparing the member function pointer to the one for a
// private undefined member function of the same name and signature in {Ast,Type}VisitorBase, which
// will be shadowed (and thus different) in case the implementation class has it.
#define DEFAULT(KIND, CLASS, PARENT) \
public: \
void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
constexpr bool hasTranslateImplementation = \
(&Self::translate##CLASS##KIND != &CrtpSubclass::translate##CLASS##KIND); \
if constexpr (hasTranslateImplementation) { \
TrapClassOf<swift::CLASS##KIND> entry{}; \
static_cast<CrtpSubclass*>(this)->translate##CLASS##KIND(e, &entry); \
dispatcher_.emit(entry); \
} else { \
dispatcher_.emitUnknown(e); \
} \
} \
\
private: \
void translate##CLASS##KIND(swift::CLASS##KIND*, TrapClassOf<swift::CLASS##KIND>*);
// superclasses by default and instead provide our own TBD default (using the exact type).
// Moreover if the implementation class has translate##CLASS##KIND (that uses generated C++
// classes), we want to use that. We detect that by comparing the member function pointer to the one
// for a private undefined member function of the same name and signature in {Ast,Type}VisitorBase,
// which will be shadowed (and thus different) in case the implementation class has it.
#define DEFAULT(KIND, CLASS, PARENT) \
public: \
void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
using TranslateResult = std::invoke_result_t<decltype(&CrtpSubclass::translate##CLASS##KIND), \
CrtpSubclass, swift::CLASS##KIND>; \
constexpr bool hasTranslateImplementation = !std::is_same_v<TranslateResult, void>; \
if constexpr (hasTranslateImplementation) { \
dispatcher_.emit(static_cast<CrtpSubclass*>(this)->translate##CLASS##KIND(*e)); \
} else { \
dispatcher_.emitUnknown(e); \
} \
} \
\
private: \
void translate##CLASS##KIND(const swift::CLASS##KIND&);
// base class for our AST visitors, getting a SwiftDispatcher member and default emission for
// unknown/TBD entities. Like `swift::ASTVisitor`, this uses CRTP (the Curiously Recurring Template
// Pattern)
template <typename CrtpSubclass>
class AstVisitorBase : public swift::ASTVisitor<CrtpSubclass>, protected detail::VisitorBase {
using Self = AstVisitorBase;
public:
using VisitorBase::VisitorBase;
@@ -73,8 +70,6 @@ class AstVisitorBase : public swift::ASTVisitor<CrtpSubclass>, protected detail:
// Pattern)
template <typename CrtpSubclass>
class TypeVisitorBase : public swift::TypeVisitor<CrtpSubclass>, protected detail::VisitorBase {
using Self = TypeVisitorBase;
public:
using VisitorBase::VisitorBase;