summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-05-21 15:36:02 -0400
committerGitHub <noreply@github.com>2020-05-21 15:36:02 -0400
commitdaf53bb2708982a2bcc6d6cc08fe88790ccf0bc2 (patch)
treed72a1f5a820db75072cc1d6055a0f35cf6feaccd /source/slang
parentd90ae365210cdecdad7f66a7b2e3993df2cbb7d4 (diff)
Non virtual accept implementation on AST types (#1351)
* First pass impl of making accept on AST node types non virtual. * A single switch for ITypeVistor on Val type. * Use ORIGIN to choose ITypeVisitor dispatch. * Don't use ORIGIN - we don't need special handling for ITypeVisitor on Val derived types.
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ast-base.h13
-rw-r--r--source/slang/slang-ast-reflect.cpp79
-rw-r--r--source/slang/slang-ast-reflect.h29
-rw-r--r--source/slang/slang-ast-support-types.h6
-rw-r--r--source/slang/slang-syntax.cpp12
5 files changed, 92 insertions, 47 deletions
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index b25c8a371..66afece19 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -74,7 +74,7 @@ class Val : public NodeBase
typedef IValVisitor Visitor;
- virtual void accept(IValVisitor* visitor, void* extra) = 0;
+ void accept(IValVisitor* visitor, void* extra);
// construct a new value by applying a set of parameter
// substitutions to this one
@@ -122,8 +122,7 @@ class Type: public Val
typedef ITypeVisitor Visitor;
- virtual void accept(IValVisitor* visitor, void* extra) override;
- virtual void accept(ITypeVisitor* visitor, void* extra) = 0;
+ void accept(ITypeVisitor* visitor, void* extra);
public:
Session* getSession() { return this->session; }
@@ -271,7 +270,7 @@ class Modifier : public SyntaxNode
SLANG_ABSTRACT_CLASS(Modifier)
typedef IModifierVisitor Visitor;
- virtual void accept(IModifierVisitor* visitor, void* extra) = 0;
+ void accept(IModifierVisitor* visitor, void* extra);
// Next modifier in linked list of modifiers on same piece of syntax
RefPtr<Modifier> next;
@@ -312,7 +311,7 @@ class DeclBase : public ModifiableSyntaxNode
typedef IDeclVisitor Visitor;
- virtual void accept(IDeclVisitor* visitor, void* extra) = 0;
+ void accept(IDeclVisitor* visitor, void* extra);
};
class Decl : public DeclBase
@@ -350,7 +349,7 @@ class Expr : public SyntaxNode
QualType type;
- virtual void accept(IExprVisitor* visitor, void* extra) = 0;
+ void accept(IExprVisitor* visitor, void* extra);
};
class Stmt : public ModifiableSyntaxNode
@@ -359,7 +358,7 @@ class Stmt : public ModifiableSyntaxNode
typedef IStmtVisitor Visitor;
- virtual void accept(IStmtVisitor* visitor, void* extra) = 0;
+ void accept(IStmtVisitor* visitor, void* extra);
};
} // namespace Slang
diff --git a/source/slang/slang-ast-reflect.cpp b/source/slang/slang-ast-reflect.cpp
index 471daf92b..eb511689d 100644
--- a/source/slang/slang-ast-reflect.cpp
+++ b/source/slang/slang-ast-reflect.cpp
@@ -9,6 +9,8 @@
#include <typeinfo>
#include <assert.h>
+#include "slang-visitor.h"
+
#include "slang-ast-generated-macro.h"
namespace Slang
@@ -66,5 +68,82 @@ struct CreateImpl
SLANG_ALL_ASTNode_NodeBase(SLANG_REFLECT_CLASS_INFO, _)
SLANG_ALL_ASTNode_Substitutions(SLANG_REFLECT_CLASS_INFO, _)
+// We dispatch to non 'abstract' types
+#define SLANG_CASE_NONE(NAME) case ASTNodeType::NAME: return visitor->dispatch_##NAME(static_cast<NAME*>(this), extra);
+#define SLANG_CASE_ABSTRACT(NAME)
+
+#define SLANG_CASE_DISPATCH(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) SLANG_CASE_##MARKER(NAME)
+
+void Val::accept(IValVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_Val(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
+
+void Type::accept(ITypeVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_Type(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
+
+void Modifier::accept(IModifierVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_Modifier(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
+
+void DeclBase::accept(IDeclVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_DeclBase(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
+
+void Expr::accept(IExprVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_Expr(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
+
+void Stmt::accept(IStmtVisitor* visitor, void* extra)
+{
+ const ReflectClassInfo& classInfo = getClassInfo();
+ const ASTNodeType astType = ASTNodeType(classInfo.m_classId);
+
+ switch (astType)
+ {
+ SLANG_CHILDREN_ASTNode_Stmt(SLANG_CASE_DISPATCH, _)
+ default: SLANG_ASSERT(!"Unknown type");
+ }
+}
} // namespace Slang
diff --git a/source/slang/slang-ast-reflect.h b/source/slang/slang-ast-reflect.h
index 0c57dc757..5384e4afd 100644
--- a/source/slang/slang-ast-reflect.h
+++ b/source/slang/slang-ast-reflect.h
@@ -10,33 +10,7 @@
#define SLANG_AST_OVERRIDE_INNER override
#define SLANG_AST_OVERRIDE_LEAF override
-// Switch based on the origin - classes defined in slang-ast-base.h do not have accept defined on them
-// The 'origin' is based on the file where the class definition is located.
-
-// Define what the accept method looks like, so don't have to repeat
-#define SLANG_AST_ACCEPT_IMPL(NAME) virtual void accept(NAME::Visitor* visitor, void* extra) override;
-
-// A macro for *all* of the different origin/files where AST files are defined.
-#define SLANG_AST_ACCEPT_BASE(NAME)
-#define SLANG_AST_ACCEPT_DECL(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-#define SLANG_AST_ACCEPT_EXPR(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-#define SLANG_AST_ACCEPT_MODIFIER(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-#define SLANG_AST_ACCEPT_TYPE(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-#define SLANG_AST_ACCEPT_VAL(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-#define SLANG_AST_ACCEPT_STMT(NAME) SLANG_AST_ACCEPT_IMPL(NAME)
-
// Implementation for SLANG_ABSTRACT_CLASS(x) using reflection from C++ extractor in slang-ast-generated.h
-#define SLANG_ABSTRACT_CLASS_REFLECT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
- public: \
- typedef SUPER Super; \
- static const ASTNodeType kType = ASTNodeType::NAME; \
- static const ReflectClassInfo kReflectClassInfo; \
- SLANG_FORCE_INLINE static bool isDerivedFrom(ASTNodeType type) { return int(type) >= int(kType) && int(type) <= int(ASTNodeType::LAST); } \
- virtual const ReflectClassInfo& getClassInfo() const SLANG_AST_OVERRIDE_##TYPE { return kReflectClassInfo; } \
-
-// Implementation for SLANG_CLASS(x) using reflection from C++ extractor in slang-ast-generated.h.
-// This implementation is the same as for SLANG_ABSTRACT_CLASS_REFLECT_IMPL, except for the SLANG_AST_ACCEPT_ line which inserts the accept
-// method for non 'BASE' origin classes.
#define SLANG_CLASS_REFLECT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
public: \
typedef SUPER Super; \
@@ -44,11 +18,10 @@
static const ReflectClassInfo kReflectClassInfo; \
SLANG_FORCE_INLINE static bool isDerivedFrom(ASTNodeType type) { return int(type) >= int(kType) && int(type) <= int(ASTNodeType::LAST); } \
virtual const ReflectClassInfo& getClassInfo() const SLANG_AST_OVERRIDE_##TYPE { return kReflectClassInfo; } \
- SLANG_AST_ACCEPT_##ORIGIN(NAME)
// Macro definitions - use the SLANG_ASTNode_ definitions to invoke the IMPL to produce the code
// injected into AST classes
-#define SLANG_ABSTRACT_CLASS(NAME) SLANG_ASTNode_##NAME(SLANG_ABSTRACT_CLASS_REFLECT_IMPL, _)
+#define SLANG_ABSTRACT_CLASS(NAME) SLANG_ASTNode_##NAME(SLANG_CLASS_REFLECT_IMPL, _)
#define SLANG_CLASS(NAME) SLANG_ASTNode_##NAME(SLANG_CLASS_REFLECT_IMPL, _)
// Does nothing - just a mark to the C++ extractor
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index c1072c923..9b8cfbea2 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -491,6 +491,12 @@ namespace Slang
// We include super.m_classId, because it's a subclass of itself.
return m_classId >= super.m_classId && m_classId <= super.m_lastClassId;
}
+ // True if typeId derives from this type
+ SLANG_FORCE_INLINE bool isDerivedFrom(uint32_t typeId) const
+ {
+ return typeId >= m_classId && typeId <= m_lastClassId;
+ }
+
/// Will produce the same result as isSubClassOf, but more slowly by traversing the m_superClass
/// Works without initRange being called.
bool isSubClassOfSlow(const ThisType& super) const;
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index cb75622bc..486466718 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -9,11 +9,6 @@
namespace Slang
{
-#define SLANG_CLASS_ACCEPT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
- void NAME::accept(NAME::Visitor* visitor, void* extra) { visitor->dispatch_##NAME(this, extra); }
-
-SLANG_ALL_ASTNode_NodeBase(SLANG_CLASS_ONLY, SLANG_CLASS_ACCEPT_IMPL)
-
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DiagnosticSink impls !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void printDiagnosticArg(StringBuilder& sb, Decl* decl)
@@ -209,13 +204,6 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
return count;
}
- // Type
-
- void Type::accept(IValVisitor* visitor, void* extra)
- {
- accept((ITypeVisitor*)visitor, extra);
- }
-
// TypeExp
bool TypeExp::Equals(Type* other)