Raw File
visitor.h
// visitor.h
#ifndef SLANG_VISITOR_H_INCLUDED
#define SLANG_VISITOR_H_INCLUDED

// This file defines the basic "Visitor" pattern for doing dispatch
// over the various categories of syntax node.

#include "syntax.h"

namespace Slang {

//
// type Visitors
//

struct ITypeVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void, typename Base = ITypeVisitor>
struct TypeVisitor : Base
{
    Result dispatch(Type* type)
    {
        Result result;
        type->accept(this, &result);
        return result;
    }

    Result dispatchType(Type* type)
    {
        Result result;
        type->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Base>
struct TypeVisitor<Derived,void,Base> : Base
{
    void dispatch(Type* type)
    {
        type->accept(this, 0);
    }

    void dispatchType(Type* type)
    {
        type->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Arg, typename Base = ITypeVisitor>
struct TypeVisitorWithArg : Base
{
    void dispatch(Type* type, Arg const& arg)
    {
        type->accept(this, (void*)&arg);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* arg) override \
    { ((Derived*) this)->visit##NAME(obj, *(Arg*)arg); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj, Arg const& arg) \
    { ((Derived*) this)->visit##BASE(obj, arg); }

#include "object-meta-begin.h"
#include "type-defs.h"
#include "object-meta-end.h"
};

//
// Expression Visitors
//

struct IExprVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void>
struct ExprVisitor : IExprVisitor
{
    Result dispatch(Expr* expr)
    {
        Result result;
        expr->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"
};

template<typename Derived>
struct ExprVisitor<Derived,void> : IExprVisitor
{
    void dispatch(Expr* expr)
    {
        expr->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Arg>
struct ExprVisitorWithArg : IExprVisitor
{
    void dispatch(Expr* obj, Arg const& arg)
    {
        obj->accept(this, (void*)&arg);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* arg) override \
    { ((Derived*) this)->visit##NAME(obj, *(Arg*)arg); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj, Arg const& arg) \
    { ((Derived*) this)->visit##BASE(obj, arg); }

#include "object-meta-begin.h"
#include "expr-defs.h"
#include "object-meta-end.h"
};

//
// Statement Visitors
//

struct IStmtVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "stmt-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void>
struct StmtVisitor : IStmtVisitor
{
    Result dispatch(Stmt* stmt)
    {
        Result result;
        stmt->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "stmt-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "stmt-defs.h"
#include "object-meta-end.h"
};

template<typename Derived>
struct StmtVisitor<Derived,void> : IStmtVisitor
{
    void dispatch(Stmt* stmt)
    {
        stmt->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "stmt-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "stmt-defs.h"
#include "object-meta-end.h"
};

//
// Declaration Visitors
//

struct IDeclVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void>
struct DeclVisitor : IDeclVisitor
{
    Result dispatch(DeclBase* decl)
    {
        Result result;
        decl->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"
};

template<typename Derived>
struct DeclVisitor<Derived,void> : IDeclVisitor
{
    void dispatch(DeclBase* decl)
    {
        decl->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Arg>
struct DeclVisitorWithArg : IDeclVisitor
{
    void dispatch(DeclBase* obj, Arg const& arg)
    {
        obj->accept(this, (void*)&arg);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* arg) override \
    { ((Derived*) this)->visit##NAME(obj, *(Arg*)arg); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj, Arg const& arg) \
    { ((Derived*) this)->visit##BASE(obj, arg); }

#include "object-meta-begin.h"
#include "decl-defs.h"
#include "object-meta-end.h"
};


//
// Modifier Visitors
//

struct IModifierVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "modifier-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void>
struct ModifierVisitor : IModifierVisitor
{
    Result dispatch(Modifier* modifier)
    {
        Result result;
        modifier->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "modifier-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "modifier-defs.h"
#include "object-meta-end.h"
};

template<typename Derived>
struct ModifierVisitor<Derived, void> : IModifierVisitor
{
    void dispatch(Modifier* modifier)
    {
        modifier->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "modifier-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "modifier-defs.h"
#include "object-meta-end.h"
};

//
// Val Visitors
//

struct IValVisitor : ITypeVisitor
{
#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;

#include "object-meta-begin.h"
#include "val-defs.h"
#include "object-meta-end.h"
};

template<typename Derived, typename Result = void, typename TypeResult = void>
struct ValVisitor : TypeVisitor<Derived, TypeResult, IValVisitor>
{
    Result dispatch(Val* val)
    {
        Result result;
        val->accept(this, &result);
        return result;
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void* extra) override \
    { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "val-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    Result visit##NAME(NAME* obj) \
    { return ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "val-defs.h"
#include "object-meta-end.h"
};

template<typename Derived>
struct ValVisitor<Derived, void, void> : TypeVisitor<Derived, void, IValVisitor>
{
    void dispatch(Val* val)
    {
        val->accept(this, 0);
    }

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
#define SYNTAX_CLASS(NAME, BASE) \
    virtual void dispatch_##NAME(NAME* obj, void*) override \
    { ((Derived*) this)->visit##NAME(obj); }

#include "object-meta-begin.h"
#include "val-defs.h"
#include "object-meta-end.h"

#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) SYNTAX_CLASS(NAME, BASE)
#define SYNTAX_CLASS(NAME, BASE) \
    void visit##NAME(NAME* obj) \
    { ((Derived*) this)->visit##BASE(obj); }

#include "object-meta-begin.h"
#include "val-defs.h"
#include "object-meta-end.h"

};

}

#endif
back to top