summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-05-29 14:26:48 -0400
committerGitHub <noreply@github.com>2020-05-29 14:26:48 -0400
commit9773495f1ab8a11194a21e1cf7b141c3da5cdfce (patch)
tree67031b547c61fba8553aee44b627b05eeeb4c4ee /source
parent45e414f9298d9fae339ff61a959f30b0529c41b9 (diff)
NodeBase types constructed with astNodeType member set (#1363)
* Maked Substituions derived from NodeBase * * Add astNodeTYpe field to NodeBase * Make Substitutions derived from NodeBase * Make all construction through ASTBuilder * Make getClassInfo non virtual (just uses the astNodeType)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ast-base.h31
-rw-r--r--source/slang/slang-ast-builder.cpp6
-rw-r--r--source/slang/slang-ast-builder.h8
-rw-r--r--source/slang/slang-ast-dump.cpp31
-rw-r--r--source/slang/slang-ast-dump.h1
-rw-r--r--source/slang/slang-ast-reflect.cpp4
-rw-r--r--source/slang/slang-ast-reflect.h6
-rw-r--r--source/slang/slang-ast-support-types.h19
-rw-r--r--source/slang/slang-check-modifier.cpp2
-rw-r--r--source/slang/slang-parser.cpp4
-rw-r--r--source/slang/slang-syntax.cpp2
11 files changed, 51 insertions, 63 deletions
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index 9e99d008f..5f40cba49 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -23,10 +23,19 @@ class NodeBase : public RefObject
{
SLANG_ABSTRACT_CLASS(NodeBase)
- // By default AST types do *not* store the builder. This is called when constructed tho.
- SLANG_FORCE_INLINE void setASTBuilder(ASTBuilder* astBuilder) { SLANG_UNUSED(astBuilder); }
+ // MUST be called before used. Called automatically via the ASTBuilder.
+ // Note that the astBuilder is not stored in the NodeBase derived types by default.
+ SLANG_FORCE_INLINE void init(ASTNodeType inAstNodeType, ASTBuilder* /* astBuilder*/ ) { astNodeType = inAstNodeType; }
+
+ /// Get the class info
+ SLANG_FORCE_INLINE const ReflectClassInfo& getClassInfo() const { return *ReflectClassInfo::getInfo(astNodeType); }
SyntaxClass<NodeBase> getClass() { return SyntaxClass<NodeBase>(&getClassInfo()); }
+
+ /// The type of the node. ASTNodeType(-1) is an invalid node type, and shouldn't appear on any
+ /// correctly constructed (through ASTBuilder) NodeBase derived class.
+ /// The actual type is set when constructed on the ASTBuilder.
+ ASTNodeType astNodeType = ASTNodeType(-1);
};
// Casting of NodeBase
@@ -34,28 +43,29 @@ class NodeBase : public RefObject
template<typename T>
SLANG_FORCE_INLINE T* dynamicCast(NodeBase* node)
{
- return (node && node->getClassInfo().isSubClassOf(T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
+ return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
}
template<typename T>
SLANG_FORCE_INLINE const T* dynamicCast(const NodeBase* node)
{
- return (node && node->getClassInfo().isSubClassOf(T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
+ return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
}
template<typename T>
SLANG_FORCE_INLINE T* as(NodeBase* node)
{
- return (node && node->getClassInfo().isSubClassOf(T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
+ return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
}
template<typename T>
SLANG_FORCE_INLINE const T* as(const NodeBase* node)
{
- return (node && node->getClassInfo().isSubClassOf(T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
+ return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
}
+
// Base class for all nodes representing actual syntax
// (thus having a location in the source code)
class SyntaxNodeBase : public NodeBase
@@ -128,8 +138,8 @@ class Type: public Val
void accept(ITypeVisitor* visitor, void* extra);
/// Type derived types store the AST builder they were constructed on. The builder calls this function
- /// after constructing
- SLANG_FORCE_INLINE void setASTBuilder(ASTBuilder* astBuilder) { m_astBuilder = astBuilder; }
+ /// after constructing.
+ SLANG_FORCE_INLINE void init(ASTNodeType inAstNodeType, ASTBuilder* inAstBuilder) { m_astBuilder = inAstBuilder; astNodeType = inAstNodeType; }
/// Get the ASTBuilder that was used to construct this Type
SLANG_FORCE_INLINE ASTBuilder* getASTBuilder() const { return m_astBuilder; }
@@ -163,13 +173,10 @@ SLANG_FORCE_INLINE const T* as(const Type* obj) { return obj ? dynamicCast<T>(co
// A substitution represents a binding of certain
// type-level variables to concrete argument values
-class Substitutions: public RefObject
+class Substitutions: public NodeBase
{
SLANG_ABSTRACT_CLASS(Substitutions)
- // By default AST types do *not* store the builder. This is called when constructed tho.
- SLANG_FORCE_INLINE void setASTBuilder(ASTBuilder* astBuilder) { SLANG_UNUSED(astBuilder); }
-
// The next outer that this one refines.
RefPtr<Substitutions> outer;
diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp
index 7e40e52ec..316390353 100644
--- a/source/slang/slang-ast-builder.cpp
+++ b/source/slang/slang-ast-builder.cpp
@@ -132,7 +132,7 @@ void SharedASTBuilder::registerMagicDecl(RefPtr<Decl> decl, RefPtr<MagicTypeModi
m_magicDecls[modifier->name] = declToRegister.Ptr();
}
-RefPtr<Decl> SharedASTBuilder::findMagicDecl(const String& name)
+RefPtr<Decl> SharedASTBuilder::findMagicDecl(const String& name)
{
return m_magicDecls[name].GetValue();
}
@@ -150,7 +150,7 @@ ASTBuilder::ASTBuilder():
{
}
-RefPtr<PtrType> ASTBuilder::getPtrType( RefPtr<Type> valueType)
+RefPtr<PtrType> ASTBuilder::getPtrType(RefPtr<Type> valueType)
{
return getPtrType(valueType, "PtrType").dynamicCast<PtrType>();
}
@@ -206,7 +206,7 @@ RefPtr<VectorExpressionType> ASTBuilder::getVectorType(
auto vectorTypeDecl = vectorGenericDecl->inner;
- auto substitutions = new GenericSubstitution();
+ auto substitutions = create<GenericSubstitution>();
substitutions->genericDecl = vectorGenericDecl.Ptr();
substitutions->args.add(elementType);
substitutions->args.add(elementCount);
diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h
index 0cb853424..bb423c4a4 100644
--- a/source/slang/slang-ast-builder.h
+++ b/source/slang/slang-ast-builder.h
@@ -85,19 +85,19 @@ public:
{
enum
{
- Value = IsBaseOf<NodeBase, T>::Value || IsBaseOf<Substitutions, T>::Value
+ Value = IsBaseOf<NodeBase, T>::Value
};
};
/// Create AST type.
template <typename T>
- T* create() { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T; node->setASTBuilder(this); return node; }
+ T* create() { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T; node->init(T::kType, this); return node; }
template<typename T, typename P0>
- T* create(const P0& p0) { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T(p0); node->setASTBuilder(this); return node;}
+ T* create(const P0& p0) { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T(p0); node->init(T::kType, this); return node;}
template<typename T, typename P0, typename P1>
- T* create(const P0& p0, const P1& p1) { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T(p0, p1); node->setASTBuilder(this); return node; }
+ T* create(const P0& p0, const P1& p1) { SLANG_COMPILE_TIME_ASSERT(IsValidType<T>::Value); T* node = new T(p0, p1); node->init(T::kType, this); return node; }
/// Get the built in types
SLANG_FORCE_INLINE Type* getBoolType() { return m_sharedASTBuilder->m_builtinTypes[Index(BaseType::Bool)]; }
diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp
index 8b9f643dd..2157b7c19 100644
--- a/source/slang/slang-ast-dump.cpp
+++ b/source/slang/slang-ast-dump.cpp
@@ -545,8 +545,13 @@ struct Context
m_writer->emit("\n");
}
+ void dump(ASTNodeType nodeType)
+ {
+ SLANG_UNUSED(nodeType)
+ // Don't bother to output anything - as will already have been dumped with the object name
+ }
+
void dumpObjectFull(NodeBase* node);
- void dumpObjectFull(Substitutions* subs);
Context(SourceWriter* writer, ASTDumpUtil::Style dumpStyle):
m_writer(writer),
@@ -585,7 +590,6 @@ static void dumpFields_##NAME(NAME* node, Context& context) \
SLANG_FIELDS_ASTNode_##NAME(SLANG_AST_DUMP_FIELD, _) \
}
-SLANG_ALL_ASTNode_Substitutions(SLANG_AST_DUMP_FIELDS_IMPL, _)
SLANG_ALL_ASTNode_NodeBase(SLANG_AST_DUMP_FIELDS_IMPL, _)
};
@@ -599,7 +603,6 @@ struct DumpFieldFuncs
DumpFieldFuncs()
{
memset(m_funcs, 0, sizeof(m_funcs));
- SLANG_ALL_ASTNode_Substitutions(SLANG_AST_GET_DUMP_FUNC, _)
SLANG_ALL_ASTNode_NodeBase(SLANG_AST_GET_DUMP_FUNC, _)
}
@@ -679,20 +682,6 @@ void Context::dumpObjectFull(NodeBase* node)
}
}
-void Context::dumpObjectFull(Substitutions* subs)
-{
- if (!subs)
- {
- _dumpPtr(nullptr);
- }
- else
- {
- const ReflectClassInfo& typeInfo = subs->getClassInfo();
- Index index = getObjectIndex(typeInfo, subs);
- dumpObjectFull(typeInfo, subs, index);
- }
-}
-
/* static */void ASTDumpUtil::dump(NodeBase* node, Style style, SourceWriter* writer)
{
Context context(writer, style);
@@ -700,12 +689,4 @@ void Context::dumpObjectFull(Substitutions* subs)
context.dumpRemaining();
}
-/* static */void ASTDumpUtil::dump(Substitutions* subs, Style style, SourceWriter* writer)
-{
- Context context(writer, style);
- context.dumpObjectFull(subs);
- context.dumpRemaining();
-
-}
-
} // namespace Slang
diff --git a/source/slang/slang-ast-dump.h b/source/slang/slang-ast-dump.h
index 71df8aafc..0a83479b1 100644
--- a/source/slang/slang-ast-dump.h
+++ b/source/slang/slang-ast-dump.h
@@ -20,7 +20,6 @@ struct ASTDumpUtil
};
static void dump(NodeBase* node, Style style, SourceWriter* writer);
- static void dump(Substitutions* subs, Style style, SourceWriter* writer);
};
} // namespace Slang
diff --git a/source/slang/slang-ast-reflect.cpp b/source/slang/slang-ast-reflect.cpp
index 7efccd3e4..689d9d93f 100644
--- a/source/slang/slang-ast-reflect.cpp
+++ b/source/slang/slang-ast-reflect.cpp
@@ -23,7 +23,6 @@ static ReflectClassInfo::Infos _calcInfos()
ReflectClassInfo::Infos infos;
memset(&infos, 0, sizeof(infos));
SLANG_ALL_ASTNode_NodeBase(SLANG_REFLECT_GET_REFLECT_CLASS_INFO, _)
- SLANG_ALL_ASTNode_Substitutions(SLANG_REFLECT_GET_REFLECT_CLASS_INFO, _)
return infos;
}
@@ -49,7 +48,7 @@ struct ASTConstructAccess
template <typename T>
struct CreateImpl
{
- static void* create() { return new T; }
+ static void* create(ASTBuilder* astBuilder) { return astBuilder->create<T>(); }
};
};
@@ -68,7 +67,6 @@ struct ASTConstructAccess
/* static */const ReflectClassInfo NAME::kReflectClassInfo = { uint32_t(ASTNodeType::NAME), uint32_t(ASTNodeType::LAST), SLANG_GET_SUPER_##TYPE(SUPER), #NAME, SLANG_GET_CREATE_FUNC_##MARKER(NAME) };
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);
diff --git a/source/slang/slang-ast-reflect.h b/source/slang/slang-ast-reflect.h
index a5875d34a..2c629e839 100644
--- a/source/slang/slang-ast-reflect.h
+++ b/source/slang/slang-ast-reflect.h
@@ -5,11 +5,6 @@
#include "slang-ast-generated.h"
-// Switch based on node type - only inner and leaf classes define override
-#define SLANG_AST_OVERRIDE_BASE
-#define SLANG_AST_OVERRIDE_INNER override
-#define SLANG_AST_OVERRIDE_LEAF override
-
// Implementation for SLANG_ABSTRACT_CLASS(x) using reflection from C++ extractor in slang-ast-generated.h
#define SLANG_CLASS_REFLECT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
protected: \
@@ -20,7 +15,6 @@
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; } \
friend class ASTBuilder; \
friend struct ASTConstructAccess;
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 3fc14e2ee..99b94f0e4 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -448,11 +448,13 @@ namespace Slang
RefPtr<Type> operator->() { return type; }
};
+ class ASTBuilder;
+
struct ReflectClassInfo
{
typedef ReflectClassInfo ThisType;
- typedef void* (*CreateFunc)();
+ typedef void* (*CreateFunc)(ASTBuilder* astBuilder);
/// A constant time implementation of isSubClassOf
SLANG_FORCE_INLINE bool isSubClassOf(const ThisType& super) const
@@ -465,6 +467,13 @@ namespace Slang
{
return typeId >= m_classId && typeId <= m_lastClassId;
}
+ SLANG_FORCE_INLINE static bool isSubClassOf(ASTNodeType type, const ThisType& super)
+ {
+ // Check the type appears valid
+ SLANG_ASSERT(int(type) >= 0);
+ // We include super.m_classId, because it's a subclass of itself.
+ return uint32_t(type) >= super.m_classId && uint32_t(type) <= super.m_lastClassId;
+ }
/// Will produce the same result as isSubClassOf, but more slowly by traversing the m_superClass
/// Works without initRange being called.
@@ -500,7 +509,7 @@ namespace Slang
: classInfo(inClassInfo)
{}
- void* createInstanceImpl() const
+ void* createInstanceImpl(ASTBuilder* astBuilder) const
{
auto ci = classInfo;
if (!ci) return nullptr;
@@ -508,7 +517,7 @@ namespace Slang
auto cf = ci->m_createFunc;
if (!cf) return nullptr;
- return cf();
+ return cf(astBuilder);
}
SLANG_FORCE_INLINE bool isSubClassOfImpl(SyntaxClassBase const& super) const { return classInfo->isSubClassOf(*super.classInfo); }
@@ -529,9 +538,9 @@ namespace Slang
{
}
- T* createInstance() const
+ T* createInstance(ASTBuilder* astBuilder) const
{
- return (T*)createInstanceImpl();
+ return (T*)createInstanceImpl(astBuilder);
}
SyntaxClass(const ReflectClassInfo* inClassInfo):
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 42a9735af..75a75ad69 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -544,7 +544,7 @@ namespace Slang
}
// Manage scope
- RefPtr<RefObject> attrInstance = attrDecl->syntaxClass.createInstance();
+ RefPtr<RefObject> attrInstance = attrDecl->syntaxClass.createInstance(m_astBuilder);
auto attr = attrInstance.as<Attribute>();
if(!attr)
{
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index a90d4bfc9..6fd51bea2 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -2834,10 +2834,10 @@ namespace Slang
// This is a catch-all syntax-construction callback to handle cases where
// a piece of syntax is fully defined by the keyword to use, along with
// the class of AST node to construct.
- static RefPtr<RefObject> parseSimpleSyntax(Parser* /*parser*/, void* userData)
+ static RefPtr<RefObject> parseSimpleSyntax(Parser* parser, void* userData)
{
SyntaxClassBase syntaxClass((ReflectClassInfo*) userData);
- return (RefObject*) syntaxClass.createInstanceImpl();
+ return (RefObject*) syntaxClass.createInstanceImpl(parser->astBuilder);
}
// Parse a declaration of a keyword that can be used to define further syntax.
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index e7876fa04..1b96aec98 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -827,7 +827,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
SLANG_UNEXPECTED("unhandled type");
}
- RefPtr<RefObject> type = classInfo.createInstance();
+ RefPtr<RefObject> type = classInfo.createInstance(astBuilder);
if (!type)
{
SLANG_UNEXPECTED("constructor failure");