Skip to content

Commit 895fcff

Browse files
author
Tim Foley
authored
Add a custom RTTI implementation for the AST (shader-slang#1148)
* Add a custom RTTI implementation for the AST Profiling was showing that the internal routines behind `dynamic_cast` were the worst offenders in the whole codebase, and a lot of this was being driven by casting inside the semantic checking logic. This change takes advantage of the fact that we *already* had a custom RTTI structure built up for the classes of syntax nodes that was previously being used to implement string->class lookup and factory services to support "magic" types and modifier in the stdlib (e.g., the way that a modifier declaration in the stdlib just lists the *name* of a C++ class that should be instantiated for it). That RTTI information already included a pointer from each syntax class to its base class (if any), based on the restriction that the AST node types form a single-inheritance hierarchy. The existing code already had a virtual `getClass()` routine on AST nodes, and an `isSubClassOf` query on the class information. Putting those pieces together to implement the `dynamicCast` and `as` routines was a cinch. The work in previous PRs to layer an abstraction over all the existing `dynamic_cast` call sites and to support type-specific `dynamicCast` implementations inside `RefPtr<>` pays off greatly here. * fixup: refactor implementation to appease more pedantic/correct compilers
1 parent 54d3c5f commit 895fcff

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

source/slang/slang-syntax.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Slang
1212

1313
bool BasicExpressionType::EqualsImpl(Type * type)
1414
{
15-
auto basicType = dynamicCast<const BasicExpressionType>(type);
15+
auto basicType = as<BasicExpressionType>(type);
1616
return basicType && basicType->baseType == this->baseType;
1717
}
1818

@@ -85,6 +85,15 @@ bool SyntaxClassBase::isSubClassOfImpl(SyntaxClassBase const& super) const
8585
return false;
8686
}
8787

88+
NodeBase* _dynamicCastImpl(NodeBase* node, SyntaxClassBase const& toClass)
89+
{
90+
if(!node) return nullptr;
91+
if(node->getClass().isSubClassOfImpl(toClass))
92+
return node;
93+
return nullptr;
94+
}
95+
96+
8897
void Type::accept(IValVisitor* visitor, void* extra)
8998
{
9099
accept((ITypeVisitor*)visitor, extra);

source/slang/slang-syntax.h

+17
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,23 @@ namespace Slang
541541
return SyntaxClass<T>::getClass();
542542
}
543543

544+
NodeBase* _dynamicCastImpl(NodeBase* node, SyntaxClassBase const& toClass);
545+
546+
template<typename T>
547+
T* dynamicCast(NodeBase* node)
548+
{
549+
return (T*) _dynamicCastImpl(node, getClass<T>());
550+
}
551+
552+
template<typename T>
553+
const T* dynamicCast(const NodeBase* node) { return dynamicCast<T>(const_cast<NodeBase*>(node)); }
554+
555+
template<typename T>
556+
T* as(NodeBase* node) { return dynamicCast<T>(node); }
557+
558+
template<typename T>
559+
const T* as(const NodeBase* node) { return dynamicCast<T>(const_cast<NodeBase*>(node)); }
560+
544561
struct SubstitutionSet
545562
{
546563
RefPtr<Substitutions> substitutions;

0 commit comments

Comments
 (0)