diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-05-29 14:26:48 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-29 14:26:48 -0400 |
| commit | 9773495f1ab8a11194a21e1cf7b141c3da5cdfce (patch) | |
| tree | 67031b547c61fba8553aee44b627b05eeeb4c4ee /source | |
| parent | 45e414f9298d9fae339ff61a959f30b0529c41b9 (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.h | 31 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-ast-dump.cpp | 31 | ||||
| -rw-r--r-- | source/slang/slang-ast-dump.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ast-reflect.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ast-reflect.h | 6 | ||||
| -rw-r--r-- | source/slang/slang-ast-support-types.h | 19 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-syntax.cpp | 2 |
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"); |
