diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-07 09:57:26 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-07 09:57:26 -0700 |
| commit | 56b44cbf582fac32e31601fd2a7ae1d6cb8f71b2 (patch) | |
| tree | 2612e7862a4b57acff0e6223caf365a88c63e62a /source/slang/visitor.h | |
| parent | 975e4b326cd2ef3ef0341d1fb7509315b9dee555 (diff) | |
Fix up visitor approach.
The existing code used a catch-all `visit()` method, and then relied on overloading to find the right version (allowing fallback to a `visit()` method taking a base-class parameter).
This approach works, but has some big down-sides:
- When browsing the code, you have a bunch of identically-named methods, and it can be hard to find the one you want.
- It is impossible to use inheritance to implement fallback for `visit()` methods, because *any* method in the derived class with that name hides *all* methods with the same name in a base class
This change makes the `visit()` methods use the name of the corresponding syntax class, and then has visitors inherit the fallback methods they need from the base visitor template class.
Diffstat (limited to 'source/slang/visitor.h')
| -rw-r--r-- | source/slang/visitor.h | 137 |
1 files changed, 116 insertions, 21 deletions
diff --git a/source/slang/visitor.h b/source/slang/visitor.h index 391769eca..eaddc5f32 100644 --- a/source/slang/visitor.h +++ b/source/slang/visitor.h @@ -24,8 +24,8 @@ struct ITypeVisitor #include "object-meta-end.h" }; -template<typename Derived, typename Result = void> -struct TypeVisitor : ITypeVisitor +template<typename Derived, typename Result = void, typename Base = ITypeVisitor> +struct TypeVisitor : Base { Result dispatch(ExpressionType* type) { @@ -37,16 +37,24 @@ struct TypeVisitor : ITypeVisitor #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(obj); } + { *(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> -struct TypeVisitor<Derived,void> : ITypeVisitor +template<typename Derived, typename Base> +struct TypeVisitor<Derived,void,Base> : Base { void dispatch(ExpressionType* type) { @@ -56,12 +64,20 @@ struct TypeVisitor<Derived,void> : ITypeVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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" }; // @@ -92,12 +108,20 @@ struct ExprVisitor : IExprVisitor #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(obj); } + { *(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> @@ -111,12 +135,20 @@ struct ExprVisitor<Derived,void> : IExprVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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" }; // @@ -147,12 +179,20 @@ struct StmtVisitor : IStmtVisitor #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(obj); } + { *(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> @@ -166,12 +206,20 @@ struct StmtVisitor<Derived,void> : IStmtVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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" }; // @@ -202,12 +250,20 @@ struct DeclVisitor : IDeclVisitor #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(obj); } + { *(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> @@ -221,12 +277,20 @@ struct DeclVisitor<Derived,void> : IDeclVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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" }; // @@ -257,12 +321,20 @@ struct ModifierVisitor : IModifierVisitor #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(obj); } + { *(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> @@ -276,12 +348,20 @@ struct ModifierVisitor<Derived, void> : IModifierVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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" }; // @@ -299,8 +379,8 @@ struct IValVisitor : ITypeVisitor #include "object-meta-end.h" }; -template<typename Derived, typename Result = void> -struct ValVisitor : IValVisitor +template<typename Derived, typename Result = void, typename TypeResult = void> +struct ValVisitor : TypeVisitor<Derived, TypeResult, IValVisitor> { Result dispatch(Val* val) { @@ -312,17 +392,24 @@ struct ValVisitor : IValVisitor #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(obj); } + { *(Result*)extra = ((Derived*) this)->visit##NAME(obj); } #include "object-meta-begin.h" #include "val-defs.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 "val-defs.h" +#include "object-meta-end.h" }; template<typename Derived> -struct ValVisitor<Derived, void> : IValVisitor +struct ValVisitor<Derived, void, void> : TypeVisitor<Derived, void, IValVisitor> { void dispatch(Val* val) { @@ -332,11 +419,19 @@ struct ValVisitor<Derived, void> : IValVisitor #define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */ #define SYNTAX_CLASS(NAME, BASE) \ virtual void dispatch_##NAME(NAME* obj, void*) override \ - { ((Derived*) this)->visit(obj); } + { ((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 "type-defs.h" #include "object-meta-end.h" }; |
