summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-10-06 17:07:22 -0400
committerGitHub <noreply@github.com>2020-10-06 14:07:22 -0700
commit4ad2e52662a00f7d8b25be6d451bba33ba62947f (patch)
treeabd70777a73037c44e40d182e332c7a19c60e779 /source
parent8a70e20df6f47678c146eb29f89655aa734f97c7 (diff)
Use Reflection for (Serial)RefObject Serialization (#1567)
* First pass at generalizing serializer. * Split out ReflectClassInfo * Use the general ReflectClassInfo * Fix some typos in debug generalized serialization. * Add calculation of classIds. Make distinct addCopy/add on SerialClasses. * Write up of more generalized serialization * WIP to transition from ASTSerialReader/Writer etc to generalized SerialReader/Writer and associated types. * Improvements to SerialExtraObjects. Keep RefObjects in scope in factory * Compiles with Serial refactor - doesn't quite work yet. * First pass serialization appears to work with refector. * Split out type info for general slang types. * Split out slang-serialize-misc-type-info.h * DebugSerialData -> SerialSourecLocData DebugSerialReader -> SerialSourceLocReader DebugSerialWriter -> SerialSourceLocWriter * Remove unused template that only compiles on VS. * Fix warning around unused function on non-VS. * Improve output of type names that are in scopes in C++ extractor. Update premake5.lua to run generation for RefObject derived types. * C++ extractor working on RefObject type. * Split out serialization functionality that spans different types into slang-serialization-factory.cpp/.h Put AST type info into header. Removed RefObjectSerialSubType - use RefObjectType Add filtering for RefObject derived types Remove construction and filteringhacks. * Set up field serialization for SerialRefObject derived types. * Fix template problem compiling on Clang/Gcc * Work in progress to make Value types work. * Added slang-value-reflect.cpp
Diffstat (limited to 'source')
-rw-r--r--source/slang/run-generators.vcxproj29
-rw-r--r--source/slang/run-generators.vcxproj.filters3
-rw-r--r--source/slang/slang-ast-base.h3
-rw-r--r--source/slang/slang-ast-reflect.h13
-rw-r--r--source/slang/slang-ast-support-types.h176
-rw-r--r--source/slang/slang-ref-object-reflect.cpp85
-rw-r--r--source/slang/slang-ref-object-reflect.h69
-rw-r--r--source/slang/slang-serialize-ast-type-info.h401
-rw-r--r--source/slang/slang-serialize-ast.cpp558
-rw-r--r--source/slang/slang-serialize-ast.h31
-rw-r--r--source/slang/slang-serialize-container.cpp5
-rw-r--r--source/slang/slang-serialize-factory.cpp133
-rw-r--r--source/slang/slang-serialize-factory.h48
-rw-r--r--source/slang/slang-serialize-misc-type-info.h5
-rw-r--r--source/slang/slang-serialize-reflection.h16
-rw-r--r--source/slang/slang-serialize-type-info.h5
-rw-r--r--source/slang/slang-serialize.cpp41
-rw-r--r--source/slang/slang-serialize.h48
-rw-r--r--source/slang/slang-value-reflect.cpp8
-rw-r--r--source/slang/slang-value-reflect.h6
-rw-r--r--source/slang/slang.vcxproj11
-rw-r--r--source/slang/slang.vcxproj.filters33
22 files changed, 999 insertions, 728 deletions
diff --git a/source/slang/run-generators.vcxproj b/source/slang/run-generators.vcxproj
index 82b993466..56924b0d5 100644
--- a/source/slang/run-generators.vcxproj
+++ b/source/slang/run-generators.vcxproj
@@ -156,6 +156,7 @@
<ItemGroup>
<ClInclude Include="..\..\prelude\slang-cpp-scalar-intrinsics.h" />
<ClInclude Include="..\..\prelude\slang-cpp-types.h" />
+ <ClInclude Include="slang-ref-object-reflect.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\core\slang-string.cpp" />
@@ -228,16 +229,24 @@
</CustomBuild>
<CustomBuild Include="slang-ast-reflect.h">
<FileType>Document</FileType>
- <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory)/ slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast- -o slang-ast-generated -output-fields</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory)/ slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast- -o slang-ast-generated -output-fields</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory)/ slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast- -o slang-ast-generated -output-fields</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory)/ slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast- -o slang-ast-generated -output-fields</Command>
- <Outputs>slang-ast-generated.h;slang-ast-generated-macro.h</Outputs>
- <Message>slang-cpp-extractor AST %(Identity)</Message>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../bin/windows-x86/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../bin/windows-x64/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../bin/windows-x86/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../bin/windows-x64/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
+"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
+"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
+"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
+"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
+"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
+"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
+"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
+"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _CLASS</Command>
+ <Outputs>../slangslang-value-generated.h;../slangslang-value-generated-macro.h;../slangslang-ref-object-generated.h;../slangslang-ref-object-generated-macro.h;../slangslang-ast-generated.h;../slangslang-ast-generated-macro.h</Outputs>
+ <Message>slang-cpp-extractor ref-object %(Identity)</Message>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">slang-ast-support-types.h;../../bin/windows-x86/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">slang-ast-support-types.h;../../bin/windows-x64/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">slang-ast-support-types.h;../../bin/windows-x86/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">slang-ast-support-types.h;../../bin/windows-x64/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/source/slang/run-generators.vcxproj.filters b/source/slang/run-generators.vcxproj.filters
index e8ec8394a..9ec19c0d7 100644
--- a/source/slang/run-generators.vcxproj.filters
+++ b/source/slang/run-generators.vcxproj.filters
@@ -15,6 +15,9 @@
<ClInclude Include="..\..\prelude\slang-cpp-types.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-ref-object-reflect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\core\slang-string.cpp">
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index 275832342..66b7d7c9e 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -14,12 +14,11 @@
// basic `Decl`, `Stmt`, `Expr`, `type`, etc. definitions come from.
namespace Slang
-{
+{
class NodeBase
{
SLANG_ABSTRACT_CLASS(NodeBase)
- SLANG_CLASS_ROOT
// MUST be called before used. Called automatically via the ASTBuilder.
// Note that the astBuilder is not stored in the NodeBase derived types by default.
diff --git a/source/slang/slang-ast-reflect.h b/source/slang/slang-ast-reflect.h
index 3b055cc87..63bd889b8 100644
--- a/source/slang/slang-ast-reflect.h
+++ b/source/slang/slang-ast-reflect.h
@@ -3,11 +3,9 @@
#ifndef SLANG_AST_REFLECT_H
#define SLANG_AST_REFLECT_H
-#include "slang-ast-generated.h"
+#include "slang-serialize-reflection.h"
-#define SLANG_CLASS_REFLECT_SUPER_BASE(SUPER)
-#define SLANG_CLASS_REFLECT_SUPER_INNER(SUPER) typedef SUPER Super;
-#define SLANG_CLASS_REFLECT_SUPER_LEAF(SUPER) typedef SUPER Super;
+#include "slang-ast-generated.h"
// 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) \
@@ -28,13 +26,6 @@
#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
-#define SLANG_REFLECT_BASE_CLASS(NAME)
-#define SLANG_REFLECTED
-#define SLANG_UNREFLECTED
-
-#define SLANG_CLASS_ROOT
-
// Macros for simulating virtual methods without virtual methods
#define SLANG_AST_NODE_INVOKE(method, methodParams) _##method##Override methodParams
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index ae2f6e6be..4cc76804c 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -9,12 +9,13 @@
#include "../core/slang-semantic-version.h"
-#include "slang-ast-generated.h"
-
-#include "slang-ast-reflect.h"
+#include "slang-ast-generated.h"
#include "slang-serialize-reflection.h"
+#include "slang-ast-reflect.h"
+#include "slang-ref-object-reflect.h"
+
#include "slang-name.h"
#include <assert.h>
@@ -444,6 +445,8 @@ namespace Slang
struct QualType
{
+ SLANG_VALUE_CLASS(QualType)
+
Type* type = nullptr;
bool isLeftValue;
@@ -1003,9 +1006,98 @@ namespace Slang
IgnoreBaseInterfaces = 1 << 0,
};
+ class SerialRefObject;
+ // Make sure C++ extractor can see the base class.
+ SLANG_PRE_DECLARE(_OBJ_CLASS, class SerialRefObject)
+
+ class LookupResultItem_Breadcrumb : public SerialRefObject
+ {
+ public:
+ SLANG_OBJ_CLASS(LookupResultItem_Breadcrumb)
+
+ enum class Kind : uint8_t
+ {
+ // The lookup process looked "through" an in-scope
+ // declaration to the fields inside of it, so that
+ // even if lookup started with a simple name `f`,
+ // it needs to result in a member expression `obj.f`.
+ Member,
+
+ // The lookup process took a pointer(-like) value, and then
+ // proceeded to derefence it and look at the thing(s)
+ // it points to instead, so that the final expression
+ // needs to have `(*obj)`
+ Deref,
+
+ // The lookup process saw a value `obj` of type `T` and
+ // took into account an in-scope constraint that says
+ // `T` is a subtype of some other type `U`, so that
+ // lookup was able to find a member through type `U`
+ // instead.
+ SuperType,
+
+ // The lookup process considered a member of an
+ // enclosing type as being in scope, so that any
+ // reference to that member needs to use a `this`
+ // expression as appropriate.
+ This,
+ };
+
+ // The kind of lookup step that was performed
+ Kind kind;
+
+ // For the `Kind::This` case, what does the implicit
+ // `this` or `This` parameter refer to?
+ //
+ enum class ThisParameterMode : uint8_t
+ {
+ ImmutableValue, // An immutable `this` value
+ MutableValue, // A mutable `this` value
+ Type, // A `This` type
+
+ Default = ImmutableValue,
+ };
+ ThisParameterMode thisParameterMode = ThisParameterMode::Default;
+
+ // As needed, a reference to the declaration that faciliated
+ // the lookup step.
+ //
+ // For a `Member` lookup step, this is the declaration whose
+ // members were implicitly pulled into scope.
+ //
+ // For a `Constraint` lookup step, this is the `ConstraintDecl`
+ // that serves to witness the subtype relationship.
+ //
+ DeclRef<Decl> declRef;
+
+ Val* val = nullptr;
+
+ // The next implicit step that the lookup process took to
+ // arrive at a final value.
+ RefPtr<LookupResultItem_Breadcrumb> next;
+
+ LookupResultItem_Breadcrumb(
+ Kind kind,
+ DeclRef<Decl> declRef,
+ Val* val,
+ RefPtr<LookupResultItem_Breadcrumb> next,
+ ThisParameterMode thisParameterMode = ThisParameterMode::Default)
+ : kind(kind)
+ , thisParameterMode(thisParameterMode)
+ , declRef(declRef)
+ , val(val)
+ , next(next)
+ {}
+ protected:
+ // Needed for serialization
+ LookupResultItem_Breadcrumb() = default;
+ };
+
// Represents one item found during lookup
struct LookupResultItem
{
+ typedef LookupResultItem_Breadcrumb Breadcrumb;
+
// Sometimes lookup finds an item, but there were additional
// "hops" taken to reach it. We need to remember these steps
// so that if/when we consturct a full expression we generate
@@ -1058,83 +1150,7 @@ namespace Slang
// the unique result (perhaps by overload resolution), then
// we can walk the list of breadcrumbs to create a full
// expression.
- class Breadcrumb : public RefObject
- {
- public:
- enum class Kind : uint8_t
- {
- // The lookup process looked "through" an in-scope
- // declaration to the fields inside of it, so that
- // even if lookup started with a simple name `f`,
- // it needs to result in a member expression `obj.f`.
- Member,
-
- // The lookup process took a pointer(-like) value, and then
- // proceeded to derefence it and look at the thing(s)
- // it points to instead, so that the final expression
- // needs to have `(*obj)`
- Deref,
-
- // The lookup process saw a value `obj` of type `T` and
- // took into account an in-scope constraint that says
- // `T` is a subtype of some other type `U`, so that
- // lookup was able to find a member through type `U`
- // instead.
- SuperType,
-
- // The lookup process considered a member of an
- // enclosing type as being in scope, so that any
- // reference to that member needs to use a `this`
- // expression as appropriate.
- This,
- };
-
- // The kind of lookup step that was performed
- Kind kind;
-
- // For the `Kind::This` case, what does the implicit
- // `this` or `This` parameter refer to?
- //
- enum class ThisParameterMode : uint8_t
- {
- ImmutableValue, // An immutable `this` value
- MutableValue, // A mutable `this` value
- Type, // A `This` type
-
- Default = ImmutableValue,
- };
- ThisParameterMode thisParameterMode = ThisParameterMode::Default;
-
- // As needed, a reference to the declaration that faciliated
- // the lookup step.
- //
- // For a `Member` lookup step, this is the declaration whose
- // members were implicitly pulled into scope.
- //
- // For a `Constraint` lookup step, this is the `ConstraintDecl`
- // that serves to witness the subtype relationship.
- //
- DeclRef<Decl> declRef;
-
- Val* val = nullptr;
-
- // The next implicit step that the lookup process took to
- // arrive at a final value.
- RefPtr<Breadcrumb> next;
-
- Breadcrumb(
- Kind kind,
- DeclRef<Decl> declRef,
- Val* val,
- RefPtr<Breadcrumb> next,
- ThisParameterMode thisParameterMode = ThisParameterMode::Default)
- : kind(kind)
- , thisParameterMode(thisParameterMode)
- , declRef(declRef)
- , val(val)
- , next(next)
- {}
- };
+
// A properly-specialized reference to the declaration that was found.
DeclRef<Decl> declRef;
diff --git a/source/slang/slang-ref-object-reflect.cpp b/source/slang/slang-ref-object-reflect.cpp
new file mode 100644
index 000000000..caf8eb6a3
--- /dev/null
+++ b/source/slang/slang-ref-object-reflect.cpp
@@ -0,0 +1,85 @@
+#include "../../slang.h"
+
+#include "slang-ref-object-reflect.h"
+
+#include "slang-ref-object-generated.h"
+#include "slang-ref-object-generated-macro.h"
+
+#include "slang-ast-support-types.h"
+
+//#include "slang-serialize.h"
+
+#include "slang-serialize-ast-type-info.h"
+
+namespace Slang
+{
+
+static const SerialClass* _addClass(SerialClasses* serialClasses, RefObjectType type, RefObjectType super, const List<SerialField>& fields)
+{
+ const SerialClass* superClass = serialClasses->getSerialClass(SerialTypeKind::RefObject, SerialSubType(super));
+ return serialClasses->add(SerialTypeKind::RefObject, SerialSubType(type), fields.getBuffer(), fields.getCount(), superClass);
+}
+
+#define SLANG_REF_OBJECT_ADD_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(SerialField::make(#FIELD_NAME, &obj->FIELD_NAME));
+
+// Note that the obj point is not nullptr, because some compilers notice this is 'indexing from null'
+// and warn/error. So we offset from 1.
+#define SLANG_REF_OBJECT_ADD_SERIAL_CLASS(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
+{ \
+ NAME* obj = SerialField::getPtr<NAME>(); \
+ SLANG_UNUSED(obj); \
+ fields.clear(); \
+ SLANG_FIELDS_RefObject_##NAME(SLANG_REF_OBJECT_ADD_SERIAL_FIELD, param) \
+ _addClass(serialClasses, RefObjectType::NAME, RefObjectType::SUPER, fields); \
+}
+
+struct RefObjectAccess
+{
+ template <typename T>
+ static void* create(void* context)
+ {
+ SLANG_UNUSED(context)
+ return new T;
+ }
+
+ static void calcClasses(SerialClasses* serialClasses)
+ {
+ // Add SerialRefObject first, and specially handle so that we add a null super class
+ serialClasses->add(SerialTypeKind::RefObject, SerialSubType(RefObjectType::SerialRefObject), nullptr, 0, nullptr);
+
+ // Add the rest in order such that Super class is always added before its children
+ List<SerialField> fields;
+ SLANG_CHILDREN_RefObject_SerialRefObject(SLANG_REF_OBJECT_ADD_SERIAL_CLASS, _)
+ }
+};
+
+#define SLANG_GET_SUPER_BASE(SUPER) nullptr
+#define SLANG_GET_SUPER_INNER(SUPER) &SUPER::kReflectClassInfo
+#define SLANG_GET_SUPER_LEAF(SUPER) &SUPER::kReflectClassInfo
+
+#define SLANG_GET_CREATE_FUNC_NONE(NAME) nullptr
+#define SLANG_GET_CREATE_FUNC_OBJ_ABSTRACT(NAME) nullptr
+#define SLANG_GET_CREATE_FUNC_OBJ(NAME) &RefObjectAccess::create<NAME>
+
+#define SLANG_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
+ /* static */const ReflectClassInfo NAME::kReflectClassInfo = { uint32_t(RefObjectType::NAME), uint32_t(RefObjectType::LAST), SLANG_GET_SUPER_##TYPE(SUPER), #NAME, SLANG_GET_CREATE_FUNC_##MARKER(NAME), nullptr, uint32_t(sizeof(NAME)), uint8_t(SLANG_ALIGN_OF(NAME)) };
+
+SLANG_ALL_RefObject_SerialRefObject(SLANG_REFLECT_CLASS_INFO, _)
+
+/* static */const SerialRefObjects SerialRefObjects::g_singleton;
+
+// Macro to set all of the entries in m_infos for SerialRefObjects
+#define SLANG_GET_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) m_infos[Index(RefObjectType::NAME)] = &NAME::kReflectClassInfo;
+
+SerialRefObjects::SerialRefObjects()
+{
+ SLANG_ALL_RefObject_SerialRefObject(SLANG_GET_REFLECT_CLASS_INFO, _)
+}
+
+/* static */SlangResult SerialRefObjects::addSerialClasses(SerialClasses* serialClasses)
+{
+ RefObjectAccess::calcClasses(serialClasses);
+ return SLANG_OK;
+}
+
+} // namespace Slang
diff --git a/source/slang/slang-ref-object-reflect.h b/source/slang/slang-ref-object-reflect.h
new file mode 100644
index 000000000..cf50c010a
--- /dev/null
+++ b/source/slang/slang-ref-object-reflect.h
@@ -0,0 +1,69 @@
+// slang-ref-object-reflect.h
+
+#ifndef SLANG_REF_OBJECT_REFLECT_H
+#define SLANG_REF_OBJECT_REFLECT_H
+
+#include "slang-serialize-reflection.h"
+
+#include "slang-ref-object-generated.h"
+
+#include "../core/slang-smart-pointer.h"
+
+class SerialClasses;
+
+struct RefObjectAccess;
+
+#define SLANG_OBJ_CLASS_REFLECT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
+ public: \
+ typedef NAME This; \
+ static const ReflectClassInfo kReflectClassInfo; \
+ virtual const ReflectClassInfo* getClassInfo() const SLANG_OVERRIDE { return &kReflectClassInfo; } \
+ \
+ friend struct RefObjectAccess; \
+ \
+ SLANG_CLASS_REFLECT_SUPER_##TYPE(SUPER) \
+
+// Placed in any SerialRefObject derived class
+#define SLANG_ABSTRACT_OBJ_CLASS(NAME) SLANG_RefObject_##NAME(SLANG_OBJ_CLASS_REFLECT_IMPL, _)
+#define SLANG_OBJ_CLASS(NAME) SLANG_RefObject_##NAME(SLANG_OBJ_CLASS_REFLECT_IMPL, _)
+
+namespace Slang
+{
+
+class SerialClasses;
+
+// Is friended such that internally we have access to construct or get members
+struct RefObjectAccess;
+
+// Base class for Serialized RefObject derived classes. The main feature is that gives away to get ReflectClassInfo
+// via getClassInfo() method
+class SerialRefObject : public RefObject
+{
+public:
+ typedef RefObject Super;
+ typedef SerialRefObject This;
+
+ static const ReflectClassInfo kReflectClassInfo;
+
+ virtual const ReflectClassInfo* getClassInfo() const { return &kReflectClassInfo; }
+};
+
+// For turning RefObjectType back to ReflectClassInfo
+struct SerialRefObjects
+{
+ /// Add serialization classes
+ static SlangResult addSerialClasses(SerialClasses* serialClasses);
+
+ static const ReflectClassInfo* getClassInfo(RefObjectType type) { return g_singleton.m_infos[Index(type)]; }
+
+
+ static const SerialRefObjects g_singleton;
+
+protected:
+ SerialRefObjects();
+ const ReflectClassInfo* m_infos[Index(RefObjectType::CountOf)];
+};
+
+} // namespace Slang
+
+#endif // SLANG_REF_OBJECT_REFLECT_H
diff --git a/source/slang/slang-serialize-ast-type-info.h b/source/slang/slang-serialize-ast-type-info.h
new file mode 100644
index 000000000..03fe61fbb
--- /dev/null
+++ b/source/slang/slang-serialize-ast-type-info.h
@@ -0,0 +1,401 @@
+// slang-serialize-ast-type-info.h
+#ifndef SLANG_SERIALIZE_AST_TYPE_INFO_H
+#define SLANG_SERIALIZE_AST_TYPE_INFO_H
+
+#include "slang-ast-support-types.h"
+#include "slang-ast-all.h"
+
+#include "slang-serialize-type-info.h"
+#include "slang-serialize-misc-type-info.h"
+
+namespace Slang {
+
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AST types !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+// SyntaxClass<T>
+template <typename T>
+struct SerialTypeInfo<SyntaxClass<T>>
+{
+ typedef SyntaxClass<T> NativeType;
+ typedef uint16_t SerialType;
+
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ SLANG_UNUSED(writer);
+ auto& src = *(const NativeType*)native;
+ auto& dst = *(SerialType*)serial;
+ dst = SerialType(src.classInfo->m_classId);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ SLANG_UNUSED(reader);
+ auto& src = *(const SerialType*)serial;
+ auto& dst = *(NativeType*)native;
+ dst.classInfo = ASTClassInfo::getInfo(ASTNodeType(src));
+ }
+};
+
+struct SerialDeclRefBaseTypeInfo
+{
+ typedef DeclRefBase NativeType;
+ struct SerialType
+ {
+ SerialIndex substitutions;
+ SerialIndex decl;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* inNative, void* outSerial)
+ {
+ SerialType& serial = *(SerialType*)outSerial;
+ const NativeType& native = *(const NativeType*)inNative;
+
+ serial.decl = writer->addPointer(native.decl);
+ serial.substitutions = writer->addPointer(native.substitutions.substitutions);
+ }
+ static void toNative(SerialReader* reader, const void* inSerial, void* outNative)
+ {
+ DeclRefBase& native = *(DeclRefBase*)(outNative);
+ const SerialType& serial = *(const SerialType*)inSerial;
+
+ native.decl = reader->getPointer(serial.decl).dynamicCast<Decl>();
+ native.substitutions.substitutions = reader->getPointer(serial.substitutions).dynamicCast<Substitutions>();
+ }
+ static const SerialFieldType* getFieldType()
+ {
+ static const SerialFieldType type = { sizeof(SerialType), uint8_t(SerialAlignment), &toSerial, &toNative };
+ return &type;
+ }
+};
+// Special case DeclRef, because it always uses the same type
+template <typename T>
+struct SerialGetFieldType<DeclRef<T>>
+{
+ static const SerialFieldType* getFieldType() { return SerialDeclRefBaseTypeInfo::getFieldType(); }
+};
+
+
+template <typename T>
+struct SerialTypeInfo<DeclRef<T>> : public SerialDeclRefBaseTypeInfo {};
+
+// MatrixCoord can just go as is
+template <>
+struct SerialTypeInfo<MatrixCoord> : SerialIdentityTypeInfo<MatrixCoord> {};
+
+
+// QualType
+
+template <>
+struct SerialTypeInfo<QualType>
+{
+ typedef QualType NativeType;
+ struct SerialType
+ {
+ SerialIndex type;
+ uint8_t isLeftValue;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto dst = (SerialType*)serial;
+ auto src = (const NativeType*)native;
+ dst->isLeftValue = src->isLeftValue ? 1 : 0;
+ dst->type = writer->addPointer(src->type);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto src = (const SerialType*)serial;
+ auto dst = (NativeType*)native;
+ dst->type = reader->getPointer(src->type).dynamicCast<Type>();
+ dst->isLeftValue = src->isLeftValue != 0;
+ }
+};
+
+
+// LookupResult::Breadcrumb
+template <>
+struct SerialTypeInfo<LookupResultItem::Breadcrumb>
+{
+ typedef LookupResultItem::Breadcrumb NativeType;
+ struct SerialType
+ {
+ NativeType::Kind kind;
+ NativeType::ThisParameterMode thisParameterMode;
+ SerialTypeInfo<DeclRef<Decl>>::SerialType declRef;
+ SerialTypeInfo<RefPtr<NativeType>> next;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& src = *(const NativeType*)native;
+ auto& dst = *(SerialType*)serial;
+
+ dst.kind = src.kind;
+ dst.thisParameterMode = src.thisParameterMode;
+ toSerialValue(writer, src.declRef, dst.declRef);
+ toSerialValue(writer, src.next, dst.next);
+ }
+
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& dst = *(NativeType*)native;
+ auto& src = *(const SerialType*)serial;
+
+ dst.kind = src.kind;
+ dst.thisParameterMode = src.thisParameterMode;
+ toNativeValue(reader, src.declRef, dst.declRef);
+ toNativeValue(reader, src.next, dst.next);
+ }
+};
+
+// LookupResultItem
+template <>
+struct SerialTypeInfo<LookupResultItem>
+{
+ typedef LookupResultItem NativeType;
+ struct SerialType
+ {
+ SerialTypeInfo<DeclRef<Decl>>::SerialType declRef;
+ SerialTypeInfo<RefPtr<NativeType::Breadcrumb>> breadcrumbs;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& src = *(const NativeType*)native;
+ auto& dst = *(SerialType*)serial;
+
+ toSerialValue(writer, src.declRef, dst.declRef);
+ toSerialValue(writer, src.breadcrumbs, dst.breadcrumbs);
+ }
+
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& dst = *(NativeType*)native;
+ auto& src = *(const SerialType*)serial;
+
+ toNativeValue(reader, src.declRef, dst.declRef);
+ toNativeValue(reader, src.breadcrumbs, dst.breadcrumbs);
+ }
+};
+
+// LookupResult
+template <>
+struct SerialTypeInfo<LookupResult>
+{
+ typedef LookupResult NativeType;
+ typedef SerialIndex SerialType;
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& src = *(const NativeType*)native;
+ auto& dst = *(SerialType*)serial;
+
+ if (src.isOverloaded())
+ {
+ // Save off as an array
+ dst = writer->addArray(src.items.getBuffer(), src.items.getCount());
+ }
+ else if (src.item.declRef.getDecl())
+ {
+ dst = writer->addArray(&src.item, 1);
+ }
+ else
+ {
+ dst = SerialIndex(0);
+ }
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& dst = *(NativeType*)native;
+ auto& src = *(const SerialType*)serial;
+
+ // Initialize
+ dst = NativeType();
+
+ List<LookupResultItem> items;
+ reader->getArray(src, items);
+
+ if (items.getCount() == 1)
+ {
+ dst.item = items[0];
+ }
+ else
+ {
+ dst.items.swapWith(items);
+ // We have to set item such that it is valid/member of items, if items is non empty
+ dst.item = dst.items[0];
+ }
+ }
+};
+
+// GlobalGenericParamSubstitution::ConstraintArg
+template <>
+struct SerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg>
+{
+ typedef GlobalGenericParamSubstitution::ConstraintArg NativeType;
+ struct SerialType
+ {
+ SerialIndex decl;
+ SerialIndex val;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& dst = *(SerialType*)serial;
+ auto& src = *(const NativeType*)native;
+
+ dst.decl = writer->addPointer(src.decl);
+ dst.val = writer->addPointer(src.val);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& src = *(const SerialType*)serial;
+ auto& dst = *(NativeType*)native;
+
+ dst.decl = reader->getPointer(src.decl).dynamicCast<Decl>();
+ dst.val = reader->getPointer(src.val).dynamicCast<Val>();
+ }
+};
+
+// ExpandedSpecializationArg
+template <>
+struct SerialTypeInfo<ExpandedSpecializationArg>
+{
+ typedef ExpandedSpecializationArg NativeType;
+ struct SerialType
+ {
+ SerialIndex val;
+ SerialIndex witness;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& dst = *(SerialType*)serial;
+ auto& src = *(const NativeType*)native;
+
+ dst.witness = writer->addPointer(src.witness);
+ dst.val = writer->addPointer(src.val);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& src = *(const SerialType*)serial;
+ auto& dst = *(NativeType*)native;
+
+ dst.witness = reader->getPointer(src.witness).dynamicCast<Val>();
+ dst.val = reader->getPointer(src.val).dynamicCast<Val>();
+ }
+};
+
+// TypeExp
+template <>
+struct SerialTypeInfo<TypeExp>
+{
+ typedef TypeExp NativeType;
+ struct SerialType
+ {
+ SerialIndex type;
+ SerialIndex expr;
+ };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& dst = *(SerialType*)serial;
+ auto& src = *(const NativeType*)native;
+
+ dst.type = writer->addPointer(src.type);
+ dst.expr = writer->addPointer(src.exp);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& src = *(const SerialType*)serial;
+ auto& dst = *(NativeType*)native;
+
+ dst.type = reader->getPointer(src.type).dynamicCast<Type>();
+ dst.exp = reader->getPointer(src.expr).dynamicCast<Expr>();
+ }
+};
+
+// DeclCheckStateExt
+template <>
+struct SerialTypeInfo<DeclCheckStateExt>
+{
+ typedef DeclCheckStateExt NativeType;
+ typedef DeclCheckStateExt::RawType SerialType;
+
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ SLANG_UNUSED(writer);
+ *(SerialType*)serial = (*(const NativeType*)native).getRaw();
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ SLANG_UNUSED(reader);
+ (*(NativeType*)serial).setRaw(*(const SerialType*)native);
+ }
+};
+
+// Modifiers
+template <>
+struct SerialTypeInfo<Modifiers>
+{
+ typedef Modifiers NativeType;
+ typedef SerialIndex SerialType;
+
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ // We need to make into an array
+ List<SerialIndex> modifierIndices;
+ for (Modifier* modifier : *(NativeType*)native)
+ {
+ modifierIndices.add(writer->addPointer(modifier));
+ }
+ *(SerialType*)serial = writer->addArray(modifierIndices.getBuffer(), modifierIndices.getCount());
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ List<Modifier*> modifiers;
+ reader->getArray(*(const SerialType*)serial, modifiers);
+
+ Modifier* prev = nullptr;
+ for (Modifier* modifier : modifiers)
+ {
+ if (prev)
+ {
+ prev->next = modifier;
+ }
+ }
+
+ NativeType& dst = *(NativeType*)native;
+ dst.first = modifiers.getCount() > 0 ? modifiers[0] : nullptr;
+ }
+};
+
+// ASTNodeType
+template <>
+struct SerialTypeInfo<ASTNodeType> : public SerialConvertTypeInfo<ASTNodeType, uint16_t> {};
+
+// LookupResultItem_Breadcrumb::ThisParameterMode
+template <>
+struct SerialTypeInfo<LookupResultItem_Breadcrumb::ThisParameterMode> : public SerialConvertTypeInfo<LookupResultItem_Breadcrumb::ThisParameterMode, uint8_t> {};
+
+// LookupResultItem_Breadcrumb::Kind
+template <>
+struct SerialTypeInfo<LookupResultItem_Breadcrumb::Kind> : public SerialConvertTypeInfo<LookupResultItem_Breadcrumb::Kind, uint8_t> {};
+
+} // namespace Slang
+
+#endif
diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp
index 65a5488a3..8310c155b 100644
--- a/source/slang/slang-serialize-ast.cpp
+++ b/source/slang/slang-serialize-ast.cpp
@@ -8,475 +8,27 @@
#include "slang-ast-support-types.h"
-// Needed for ModuleSerialFilter
-// Needed for 'findModuleForDecl'
-#include "slang-legalize-types.h"
-#include "slang-mangle.h"
+#include "slang-serialize-ast-type-info.h"
-#include "slang-serialize-type-info.h"
-#include "slang-serialize-misc-type-info.h"
+#include "slang-serialize-factory.h"
namespace Slang {
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ModuleSerialFilter !!!!!!!!!!!!!!!!!!!!!!!!
-
-SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBase* inPtr)
-{
- NodeBase* ptr = const_cast<NodeBase*>(inPtr);
- SLANG_ASSERT(ptr);
-
- if (Decl* decl = as<Decl>(ptr))
- {
- ModuleDecl* moduleDecl = findModuleForDecl(decl);
- SLANG_ASSERT(moduleDecl);
- if (moduleDecl && moduleDecl != m_moduleDecl)
- {
- ASTBuilder* astBuilder = m_moduleDecl->module->getASTBuilder();
-
- // It's a reference to a declaration in another module, so create an ImportExternalDecl.
-
- String mangledName = getMangledName(astBuilder, decl);
-
- ImportExternalDecl* importDecl = astBuilder->create<ImportExternalDecl>();
- importDecl->mangledName = mangledName;
- const SerialIndex index = writer->addPointer(importDecl);
-
- // Set as the index of this
- writer->setPointerIndex(ptr, index);
-
- return index;
- }
- else
- {
- // Okay... we can just write it out then
- return writer->writeObject(ptr);
- }
- }
-
- // TODO(JS): What we really want to do here is to ignore bodies functions.
- // It's not 100% clear if this is even right though - for example does type inference
- // imply the body is needed to say infer a return type?
- // Also not clear if statements in other scenarios (if there are others) might need to be kept.
- //
- // For now we just ignore all stmts
-
- if (Stmt* stmt = as<Stmt>(ptr))
- {
- //
- writer->setPointerIndex(stmt, SerialIndex(0));
- return SerialIndex(0);
- }
-
- // For now for everything else just write it
- return writer->writeObject(ptr);
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AST types !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-// SyntaxClass<T>
-template <typename T>
-struct SerialTypeInfo<SyntaxClass<T>>
-{
- typedef SyntaxClass<T> NativeType;
- typedef uint16_t SerialType;
-
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- SLANG_UNUSED(writer);
- auto& src = *(const NativeType*)native;
- auto& dst = *(SerialType*)serial;
- dst = SerialType(src.classInfo->m_classId);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- SLANG_UNUSED(reader);
- auto& src = *(const SerialType*)serial;
- auto& dst = *(NativeType*)native;
- dst.classInfo = ASTClassInfo::getInfo(ASTNodeType(src));
- }
-};
-
-struct SerialDeclRefBaseTypeInfo
-{
- typedef DeclRefBase NativeType;
- struct SerialType
- {
- SerialIndex substitutions;
- SerialIndex decl;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* inNative, void* outSerial)
- {
- SerialType& serial = *(SerialType*)outSerial;
- const NativeType& native = *(const NativeType*)inNative;
-
- serial.decl = writer->addPointer(native.decl);
- serial.substitutions = writer->addPointer(native.substitutions.substitutions);
- }
- static void toNative(SerialReader* reader, const void* inSerial, void* outNative)
- {
- DeclRefBase& native = *(DeclRefBase*)(outNative);
- const SerialType& serial = *(const SerialType*)inSerial;
-
- native.decl = reader->getPointer(serial.decl).dynamicCast<Decl>();
- native.substitutions.substitutions = reader->getPointer(serial.substitutions).dynamicCast<Substitutions>();
- }
- static const SerialFieldType* getFieldType()
- {
- static const SerialFieldType type = { sizeof(SerialType), uint8_t(SerialAlignment), &toSerial, &toNative };
- return &type;
- }
-};
-// Special case DeclRef, because it always uses the same type
-template <typename T>
-struct SerialGetFieldType<DeclRef<T>>
-{
- static const SerialFieldType* getFieldType() { return SerialDeclRefBaseTypeInfo::getFieldType(); }
-};
-
-
-template <typename T>
-struct SerialTypeInfo<DeclRef<T>> : public SerialDeclRefBaseTypeInfo {};
-
-// MatrixCoord can just go as is
-template <>
-struct SerialTypeInfo<MatrixCoord> : SerialIdentityTypeInfo<MatrixCoord> {};
-
-
-// QualType
-
-template <>
-struct SerialTypeInfo<QualType>
-{
- typedef QualType NativeType;
- struct SerialType
- {
- SerialIndex type;
- uint8_t isLeftValue;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto dst = (SerialType*)serial;
- auto src = (const NativeType*)native;
- dst->isLeftValue = src->isLeftValue ? 1 : 0;
- dst->type = writer->addPointer(src->type);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto src = (const SerialType*)serial;
- auto dst = (NativeType*)native;
- dst->type = reader->getPointer(src->type).dynamicCast<Type>();
- dst->isLeftValue = src->isLeftValue != 0;
- }
-};
-
-
-// LookupResult::Breadcrumb
-template <>
-struct SerialTypeInfo<LookupResultItem::Breadcrumb>
-{
- typedef LookupResultItem::Breadcrumb NativeType;
- struct SerialType
- {
- NativeType::Kind kind;
- NativeType::ThisParameterMode thisParameterMode;
- SerialTypeInfo<DeclRef<Decl>>::SerialType declRef;
- SerialTypeInfo<RefPtr<NativeType>> next;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& src = *(const NativeType*)native;
- auto& dst = *(SerialType*)serial;
-
- dst.kind = src.kind;
- dst.thisParameterMode = src.thisParameterMode;
- toSerialValue(writer, src.declRef, dst.declRef);
- toSerialValue(writer, src.next, dst.next);
- }
-
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& dst = *(NativeType*)native;
- auto& src = *(const SerialType*)serial;
-
- dst.kind = src.kind;
- dst.thisParameterMode = src.thisParameterMode;
- toNativeValue(reader, src.declRef, dst.declRef);
- toNativeValue(reader, src.next, dst.next);
- }
-};
-
-// LookupResultItem
-template <>
-struct SerialTypeInfo<LookupResultItem>
-{
- typedef LookupResultItem NativeType;
- struct SerialType
- {
- SerialTypeInfo<DeclRef<Decl>>::SerialType declRef;
- SerialTypeInfo<RefPtr<NativeType::Breadcrumb>> breadcrumbs;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& src = *(const NativeType*)native;
- auto& dst = *(SerialType*)serial;
-
- toSerialValue(writer, src.declRef, dst.declRef);
- toSerialValue(writer, src.breadcrumbs, dst.breadcrumbs);
- }
-
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& dst = *(NativeType*)native;
- auto& src = *(const SerialType*)serial;
-
- toNativeValue(reader, src.declRef, dst.declRef);
- toNativeValue(reader, src.breadcrumbs, dst.breadcrumbs);
- }
-};
-
-// LookupResult
-template <>
-struct SerialTypeInfo<LookupResult>
-{
- typedef LookupResult NativeType;
- typedef SerialIndex SerialType;
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& src = *(const NativeType*)native;
- auto& dst = *(SerialType*)serial;
-
- if (src.isOverloaded())
- {
- // Save off as an array
- dst = writer->addArray(src.items.getBuffer(), src.items.getCount());
- }
- else if (src.item.declRef.getDecl())
- {
- dst = writer->addArray(&src.item, 1);
- }
- else
- {
- dst = SerialIndex(0);
- }
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& dst = *(NativeType*)native;
- auto& src = *(const SerialType*)serial;
-
- // Initialize
- dst = NativeType();
-
- List<LookupResultItem> items;
- reader->getArray(src, items);
-
- if (items.getCount() == 1)
- {
- dst.item = items[0];
- }
- else
- {
- dst.items.swapWith(items);
- // We have to set item such that it is valid/member of items, if items is non empty
- dst.item = dst.items[0];
- }
- }
-};
-
-// GlobalGenericParamSubstitution::ConstraintArg
-template <>
-struct SerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg>
-{
- typedef GlobalGenericParamSubstitution::ConstraintArg NativeType;
- struct SerialType
- {
- SerialIndex decl;
- SerialIndex val;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& dst = *(SerialType*)serial;
- auto& src = *(const NativeType*)native;
-
- dst.decl = writer->addPointer(src.decl);
- dst.val = writer->addPointer(src.val);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& src = *(const SerialType*)serial;
- auto& dst = *(NativeType*)native;
-
- dst.decl = reader->getPointer(src.decl).dynamicCast<Decl>();
- dst.val = reader->getPointer(src.val).dynamicCast<Val>();
- }
-};
-
-// ExpandedSpecializationArg
-template <>
-struct SerialTypeInfo<ExpandedSpecializationArg>
-{
- typedef ExpandedSpecializationArg NativeType;
- struct SerialType
- {
- SerialIndex val;
- SerialIndex witness;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& dst = *(SerialType*)serial;
- auto& src = *(const NativeType*)native;
-
- dst.witness = writer->addPointer(src.witness);
- dst.val = writer->addPointer(src.val);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& src = *(const SerialType*)serial;
- auto& dst = *(NativeType*)native;
-
- dst.witness = reader->getPointer(src.witness).dynamicCast<Val>();
- dst.val = reader->getPointer(src.val).dynamicCast<Val>();
- }
-};
-
-// TypeExp
-template <>
-struct SerialTypeInfo<TypeExp>
-{
- typedef TypeExp NativeType;
- struct SerialType
- {
- SerialIndex type;
- SerialIndex expr;
- };
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& dst = *(SerialType*)serial;
- auto& src = *(const NativeType*)native;
-
- dst.type = writer->addPointer(src.type);
- dst.expr = writer->addPointer(src.exp);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- auto& src = *(const SerialType*)serial;
- auto& dst = *(NativeType*)native;
-
- dst.type = reader->getPointer(src.type).dynamicCast<Type>();
- dst.exp = reader->getPointer(src.expr).dynamicCast<Expr>();
- }
-};
-
-// DeclCheckStateExt
-template <>
-struct SerialTypeInfo<DeclCheckStateExt>
-{
- typedef DeclCheckStateExt NativeType;
- typedef DeclCheckStateExt::RawType SerialType;
-
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- SLANG_UNUSED(writer);
- *(SerialType*)serial = (*(const NativeType*)native).getRaw();
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- SLANG_UNUSED(reader);
- (*(NativeType*)serial).setRaw(*(const SerialType*)native);
- }
-};
-
-// Modifiers
-template <>
-struct SerialTypeInfo<Modifiers>
-{
- typedef Modifiers NativeType;
- typedef SerialIndex SerialType;
-
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
-
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- // We need to make into an array
- List<SerialIndex> modifierIndices;
- for (Modifier* modifier : *(NativeType*)native)
- {
- modifierIndices.add(writer->addPointer(modifier));
- }
- *(SerialType*)serial = writer->addArray(modifierIndices.getBuffer(), modifierIndices.getCount());
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
- {
- List<Modifier*> modifiers;
- reader->getArray(*(const SerialType*)serial, modifiers);
-
- Modifier* prev = nullptr;
- for (Modifier* modifier : modifiers)
- {
- if (prev)
- {
- prev->next = modifier;
- }
- }
-
- NativeType& dst = *(NativeType*)native;
- dst.first = modifiers.getCount() > 0 ? modifiers[0] : nullptr;
- }
-};
-
-// ASTNodeType
-template <>
-struct SerialTypeInfo<ASTNodeType> : public SerialConvertTypeInfo<ASTNodeType, uint16_t> {};
-
// !!!!!!!!!!!!!!!!!!!!!! Generate fields for a type !!!!!!!!!!!!!!!!!!!!!!!!!!!
-template <typename T>
-SerialField _makeField(const char* name, T& in)
-{
- uint8_t* ptr = &reinterpret_cast<uint8_t&>(in);
-
- SerialField field;
- field.name = name;
- field.type = SerialGetFieldType<T>::getFieldType();
- // This only works because we in is an offset from 1
- field.nativeOffset = uint32_t(size_t(ptr) - 1);
- field.serialOffset = 0;
- return field;
-}
-
static const SerialClass* _addClass(SerialClasses* serialClasses, ASTNodeType type, ASTNodeType super, const List<SerialField>& fields)
{
const SerialClass* superClass = serialClasses->getSerialClass(SerialTypeKind::NodeBase, SerialSubType(super));
return serialClasses->add(SerialTypeKind::NodeBase, SerialSubType(type), fields.getBuffer(), fields.getCount(), superClass);
}
-#define SLANG_AST_ADD_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(_makeField(#FIELD_NAME, obj->FIELD_NAME));
+#define SLANG_AST_ADD_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(SerialField::make(#FIELD_NAME, &obj->FIELD_NAME));
// Note that the obj point is not nullptr, because some compilers notice this is 'indexing from null'
// and warn/error. So we offset from 1.
#define SLANG_AST_ADD_SERIAL_CLASS(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
{ \
- NAME* obj = (NAME*)1; \
+ NAME* obj = SerialField::getPtr<NAME>(); \
SLANG_UNUSED(obj); \
fields.clear(); \
SLANG_FIELDS_ASTNode_##NAME(SLANG_AST_ADD_SERIAL_FIELD, param) \
@@ -496,108 +48,18 @@ struct ASTFieldAccess
}
};
-void addASTTypes(SerialClasses* serialClasses)
-{
- {
- ASTFieldAccess::calcClasses(serialClasses);
- }
-
- {
- {
- // Let's hack Breadcrumbs...
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerialUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!
- typedef LookupResultItem::Breadcrumb Type;
- Type* obj = (Type*)1;
- SerialField field = _makeField("_", *obj);
- serialClasses->add(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::LookupResultItem_Breadcrumb), &field, 1, nullptr);
- }
-
- // Set these types to not serialize
- serialClasses->addUnserialized(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::Module));
- serialClasses->addUnserialized(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::Scope));
- }
-}
-
-// A Hack for now to turn an RefObject* into a SubType for serialization
-extern RefObjectSerialSubType getRefObjectSubType(const RefObject* obj)
+/* static */void ASTSerialUtil::addSerialClasses(SerialClasses* serialClasses)
{
- if (as<LookupResultItem::Breadcrumb>(obj))
- {
- return RefObjectSerialSubType::LookupResultItem_Breadcrumb;
- }
- else if (as<Module>(obj))
- {
- return RefObjectSerialSubType::Module;
- }
- else if (as<Scope>(obj))
- {
- return RefObjectSerialSubType::Scope;
- }
- return RefObjectSerialSubType::Invalid;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!! DefaultSerialObjectFactory !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-void* DefaultSerialObjectFactory::create(SerialTypeKind typeKind, SerialSubType subType)
-{
- switch (typeKind)
- {
- case SerialTypeKind::NodeBase:
- {
- return m_astBuilder->createByNodeType(ASTNodeType(subType));
- }
- case SerialTypeKind::RefObject:
- {
- switch (RefObjectSerialSubType(subType))
- {
- case RefObjectSerialSubType::LookupResultItem_Breadcrumb:
- {
- typedef LookupResultItem::Breadcrumb Breadcrumb;
- return _add(new LookupResultItem::Breadcrumb(Breadcrumb::Kind::Member, DeclRef<Decl>(), nullptr, nullptr));
- }
- default: break;
- }
- }
- default: break;
- }
-
- return nullptr;
+ ASTFieldAccess::calcClasses(serialClasses);
}
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerializeUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-/* static */SlangResult ASTSerialTestUtil::selfTest()
+
+/* static */SlangResult ASTSerialUtil::testSerialize(NodeBase* node, RootNamePool* rootNamePool, SharedASTBuilder* sharedASTBuilder, SourceManager* sourceManager)
{
RefPtr<SerialClasses> classes;
- SerialClasses::create(classes);
- {
- const SerialFieldType* type = SerialGetFieldType<Type*>::getFieldType();
- SLANG_UNUSED(type);
- }
-
- {
- const SerialFieldType* type = SerialGetFieldType<int[10]>::getFieldType();
- SLANG_UNUSED(type);
- }
-
- {
- const SerialFieldType* type = SerialGetFieldType<bool[3]>::getFieldType();
- SLANG_UNUSED(type);
- }
-
- {
- const SerialFieldType* type = SerialGetFieldType<Type*[3]>::getFieldType();
- SLANG_UNUSED(type);
- }
-
- return SLANG_OK;
-}
-
-/* static */SlangResult ASTSerialTestUtil::testSerialize(NodeBase* node, RootNamePool* rootNamePool, SharedASTBuilder* sharedASTBuilder, SourceManager* sourceManager)
-{
- RefPtr<SerialClasses> classes;
- SerialClasses::create(classes);
+ SerialClassesUtil::create(classes);
List<uint8_t> contents;
diff --git a/source/slang/slang-serialize-ast.h b/source/slang/slang-serialize-ast.h
index e2b9a956a..3aa790c86 100644
--- a/source/slang/slang-serialize-ast.h
+++ b/source/slang/slang-serialize-ast.h
@@ -30,6 +30,7 @@ class ModuleSerialFilter : public SerialFilter
public:
// SerialFilter impl
virtual SerialIndex writePointer(SerialWriter* writer, const NodeBase* ptr) SLANG_OVERRIDE;
+ virtual SerialIndex writePointer(SerialWriter* writer, const RefObject* ptr) SLANG_OVERRIDE;
ModuleSerialFilter(ModuleDecl* moduleDecl):
m_moduleDecl(moduleDecl)
@@ -39,34 +40,10 @@ public:
ModuleDecl* m_moduleDecl;
};
-class DefaultSerialObjectFactory : public SerialObjectFactory
+struct ASTSerialUtil
{
-public:
-
- virtual void* create(SerialTypeKind typeKind, SerialSubType subType) SLANG_OVERRIDE;
-
- DefaultSerialObjectFactory(ASTBuilder* astBuilder) :
- m_astBuilder(astBuilder)
- {
- }
-
-protected:
- RefObject* _add(RefObject* obj)
- {
- m_scope.add(obj);
- return obj;
- }
-
- // We keep RefObjects in scope
- List<RefPtr<RefObject>> m_scope;
- ASTBuilder* m_astBuilder;
-};
-
-/* None of the functions in this util should *not* be called from production code,
-they exist to test features of AST Serialization */
-struct ASTSerialTestUtil
-{
- static SlangResult selfTest();
+ /// Add the AST related classes
+ static void addSerialClasses(SerialClasses* classes);
/// Tries to serialize out, read back in and test the results are the same.
/// Will write dumped out node to files
diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp
index 3d5b234ff..7dd2c15a1 100644
--- a/source/slang/slang-serialize-container.cpp
+++ b/source/slang/slang-serialize-container.cpp
@@ -10,6 +10,7 @@
#include "slang-serialize-ast.h"
#include "slang-serialize-ir.h"
#include "slang-serialize-source-loc.h"
+#include "slang-serialize-factory.h"
namespace Slang {
@@ -143,7 +144,7 @@ namespace Slang {
{
if (!serialClasses)
{
- SLANG_RETURN_ON_FAIL(SerialClasses::create(serialClasses));
+ SLANG_RETURN_ON_FAIL(SerialClassesUtil::create(serialClasses));
}
ModuleSerialFilter filter(moduleDecl);
@@ -295,7 +296,7 @@ namespace Slang {
{
if (!serialClasses)
{
- SLANG_RETURN_ON_FAIL(SerialClasses::create(serialClasses));
+ SLANG_RETURN_ON_FAIL(SerialClassesUtil::create(serialClasses));
}
// TODO(JS): We probably want to store off better information about each of the translation unit
diff --git a/source/slang/slang-serialize-factory.cpp b/source/slang/slang-serialize-factory.cpp
new file mode 100644
index 000000000..2bb7b047e
--- /dev/null
+++ b/source/slang/slang-serialize-factory.cpp
@@ -0,0 +1,133 @@
+// slang-serialize-factory.cpp
+#include "slang-serialize-factory.h"
+
+#include "../core/slang-math.h"
+
+#include "slang-ast-builder.h"
+
+#include "slang-ref-object-reflect.h"
+#include "slang-ast-reflect.h"
+
+#include "slang-serialize-ast.h"
+#include "slang-ref-object-reflect.h"
+
+// Needed for ModuleSerialFilter
+// Needed for 'findModuleForDecl'
+#include "slang-legalize-types.h"
+#include "slang-mangle.h"
+
+namespace Slang {
+
+/* !!!!!!!!!!!!!!!!!!!!!! DefaultSerialObjectFactory !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* DefaultSerialObjectFactory::create(SerialTypeKind typeKind, SerialSubType subType)
+{
+ switch (typeKind)
+ {
+ case SerialTypeKind::NodeBase:
+ {
+ return m_astBuilder->createByNodeType(ASTNodeType(subType));
+ }
+ case SerialTypeKind::RefObject:
+ {
+ const ReflectClassInfo* info = SerialRefObjects::getClassInfo(RefObjectType(subType));
+
+ if (info && info->m_createFunc)
+ {
+ RefObject* obj = reinterpret_cast<RefObject*>(info->m_createFunc(nullptr));
+ return _add(obj);
+ }
+ return nullptr;
+ }
+ default: break;
+ }
+
+ return nullptr;
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ModuleSerialFilter !!!!!!!!!!!!!!!!!!!!!!!!
+
+SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const RefObject* inPtr)
+{
+ // We don't serialize Module or Scope
+ if (as<Module>(inPtr) || as<Scope>(inPtr))
+ {
+ writer->setPointerIndex(inPtr, SerialIndex(0));
+ return SerialIndex(0);
+ }
+
+ // For now for everything else just write it
+ return writer->writeObject(inPtr);
+}
+
+SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBase* inPtr)
+{
+ NodeBase* ptr = const_cast<NodeBase*>(inPtr);
+ SLANG_ASSERT(ptr);
+
+ if (Decl* decl = as<Decl>(ptr))
+ {
+ ModuleDecl* moduleDecl = findModuleForDecl(decl);
+ SLANG_ASSERT(moduleDecl);
+ if (moduleDecl && moduleDecl != m_moduleDecl)
+ {
+ ASTBuilder* astBuilder = m_moduleDecl->module->getASTBuilder();
+
+ // It's a reference to a declaration in another module, so create an ImportExternalDecl.
+
+ String mangledName = getMangledName(astBuilder, decl);
+
+ ImportExternalDecl* importDecl = astBuilder->create<ImportExternalDecl>();
+ importDecl->mangledName = mangledName;
+ const SerialIndex index = writer->addPointer(importDecl);
+
+ // Set as the index of this
+ writer->setPointerIndex(ptr, index);
+
+ return index;
+ }
+ else
+ {
+ // Okay... we can just write it out then
+ return writer->writeObject(ptr);
+ }
+ }
+
+ // TODO(JS): What we really want to do here is to ignore bodies functions.
+ // It's not 100% clear if this is even right though - for example does type inference
+ // imply the body is needed to say infer a return type?
+ // Also not clear if statements in other scenarios (if there are others) might need to be kept.
+ //
+ // For now we just ignore all stmts
+
+ if (Stmt* stmt = as<Stmt>(ptr))
+ {
+ //
+ writer->setPointerIndex(stmt, SerialIndex(0));
+ return SerialIndex(0);
+ }
+
+ // For now for everything else just write it
+ return writer->writeObject(ptr);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SerialClassesUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */SlangResult SerialClassesUtil::addSerialClasses(SerialClasses* serialClasses)
+{
+ ASTSerialUtil::addSerialClasses(serialClasses);
+ SerialRefObjects::addSerialClasses(serialClasses);
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult SerialClassesUtil::create(RefPtr<SerialClasses>& out)
+{
+ RefPtr<SerialClasses> classes(new SerialClasses);
+ SLANG_RETURN_ON_FAIL(addSerialClasses(classes));
+
+ out = classes;
+ return SLANG_OK;
+}
+
+} // namespace Slang
diff --git a/source/slang/slang-serialize-factory.h b/source/slang/slang-serialize-factory.h
new file mode 100644
index 000000000..7e51a840d
--- /dev/null
+++ b/source/slang/slang-serialize-factory.h
@@ -0,0 +1,48 @@
+// slang-serialize-factory.h
+#ifndef SLANG_SERIALIZE_FACTORY_H
+#define SLANG_SERIALIZE_FACTORY_H
+
+#include "slang-serialize.h"
+
+namespace Slang {
+
+// !!!!!!!!!!!!!!!!!!!!! DefaultSerialObjectFactory !!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+class ASTBuilder;
+
+class DefaultSerialObjectFactory : public SerialObjectFactory
+{
+public:
+
+ virtual void* create(SerialTypeKind typeKind, SerialSubType subType) SLANG_OVERRIDE;
+
+ DefaultSerialObjectFactory(ASTBuilder* astBuilder) :
+ m_astBuilder(astBuilder)
+ {
+ }
+
+protected:
+ RefObject* _add(RefObject* obj)
+ {
+ m_scope.add(obj);
+ return obj;
+ }
+
+ // We keep RefObjects in scope
+ List<RefPtr<RefObject>> m_scope;
+ ASTBuilder* m_astBuilder;
+};
+
+
+struct SerialClassesUtil
+{
+ /// Add all types to serialClasses
+ static SlangResult addSerialClasses(SerialClasses* serialClasses);
+ /// Create SerialClasses with all the types added
+ static SlangResult create(RefPtr<SerialClasses>& out);
+};
+
+
+} // namespace Slang
+
+#endif
diff --git a/source/slang/slang-serialize-misc-type-info.h b/source/slang/slang-serialize-misc-type-info.h
index bdcbf2c98..08fd1269d 100644
--- a/source/slang/slang-serialize-misc-type-info.h
+++ b/source/slang/slang-serialize-misc-type-info.h
@@ -12,6 +12,11 @@ namespace Slang {
/* Conversion for serialization for some more misc Slang types
*/
+
+// Because is sized, we don't need to convert
+template <>
+struct SerialTypeInfo<FeedbackType::Kind> : public SerialIdentityTypeInfo<FeedbackType::Kind> {};
+
// SamplerStateFlavor
template <>
diff --git a/source/slang/slang-serialize-reflection.h b/source/slang/slang-serialize-reflection.h
index 045b7bf97..a6889f795 100644
--- a/source/slang/slang-serialize-reflection.h
+++ b/source/slang/slang-serialize-reflection.h
@@ -57,6 +57,22 @@ struct ReflectClassInfo
uint8_t m_alignment; ///< The required alignment of the type
};
+// Does nothing - just a mark to the C++ extractor
+#define SLANG_REFLECTED
+#define SLANG_UNREFLECTED
+
+#define SLANG_PRE_DECLARE(SUFFIX, DEF)
+
+// Use these macros to help define Super, and making the base definition NOT have a Super definition.
+// For example something like...
+
+#define SLANG_CLASS_REFLECT_SUPER_BASE(SUPER)
+#define SLANG_CLASS_REFLECT_SUPER_INNER(SUPER) typedef SUPER Super;
+#define SLANG_CLASS_REFLECT_SUPER_LEAF(SUPER) typedef SUPER Super;
+
+// Mark a value class
+#define SLANG_VALUE_CLASS(x)
+
} // namespace Slang
#endif
diff --git a/source/slang/slang-serialize-type-info.h b/source/slang/slang-serialize-type-info.h
index 5440fc201..89097fc32 100644
--- a/source/slang/slang-serialize-type-info.h
+++ b/source/slang/slang-serialize-type-info.h
@@ -62,11 +62,6 @@ struct SerialIdentityTypeInfo
template <>
struct SerialTypeInfo<SerialIndex> : public SerialIdentityTypeInfo<SerialIndex> {};
-
-// Because is sized, we don't need to convert
-template <>
-struct SerialTypeInfo<FeedbackType::Kind> : public SerialIdentityTypeInfo<FeedbackType::Kind> {};
-
// Implement for Basic Types
template <>
diff --git a/source/slang/slang-serialize.cpp b/source/slang/slang-serialize.cpp
index 06ddbdde0..46aae18b2 100644
--- a/source/slang/slang-serialize.cpp
+++ b/source/slang/slang-serialize.cpp
@@ -156,24 +156,6 @@ SerialClasses::SerialClasses():
{
}
-// For now just use an extern so we don't need to include AST serialize
-extern void addASTTypes(SerialClasses* serialClasses);
-extern RefObjectSerialSubType getRefObjectSubType(const RefObject* obj);
-
-/* static */SlangResult SerialClasses::create(RefPtr<SerialClasses>& out)
-{
- RefPtr<SerialClasses> classes(new SerialClasses);
- addASTTypes(classes);
-
- out = classes;
- return SLANG_OK;
-}
-
-/* static */RefObjectSerialSubType SerialClasses::getSubType(const RefObject* obj)
-{
- return getRefObjectSubType(obj);
-}
-
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SerialWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!
SerialWriter::SerialWriter(SerialClasses* classes, SerialFilter* filter) :
@@ -238,14 +220,17 @@ SerialIndex SerialWriter::writeObject(const NodeBase* node)
SerialIndex SerialWriter::writeObject(const RefObject* obj)
{
- const RefObjectSerialSubType subType = SerialClasses::getSubType(obj);
- if (subType == RefObjectSerialSubType::Invalid)
+ const SerialRefObject* serialObj = as<const SerialRefObject>(obj);
+ if (!serialObj)
{
SLANG_ASSERT(!"Unhandled type");
return SerialIndex(0);
}
- const SerialClass* serialClass = m_classes->getSerialClass(SerialTypeKind::RefObject, SerialSubType(subType));
+ const ReflectClassInfo* classInfo = serialObj->getClassInfo();
+ SLANG_ASSERT(classInfo);
+
+ const SerialClass* serialClass = m_classes->getSerialClass(SerialTypeKind::RefObject, SerialSubType(classInfo->m_classId));
return writeObject(serialClass, (const void*)obj);
}
@@ -254,6 +239,11 @@ void SerialWriter::setPointerIndex(const NodeBase* ptr, SerialIndex index)
m_ptrMap.Add(ptr, Index(index));
}
+void SerialWriter::setPointerIndex(const RefObject* ptr, SerialIndex index)
+{
+ m_ptrMap.Add(ptr, Index(index));
+}
+
SerialIndex SerialWriter::addPointer(const NodeBase* node)
{
// Null is always 0
@@ -307,7 +297,14 @@ SerialIndex SerialWriter::addPointer(const RefObject* obj)
return addName(name);
}
- return writeObject(obj);
+ if (m_filter)
+ {
+ return m_filter->writePointer(this, obj);
+ }
+ else
+ {
+ return writeObject(obj);
+ }
}
SerialIndex SerialWriter::addString(const UnownedStringSlice& slice)
diff --git a/source/slang/slang-serialize.h b/source/slang/slang-serialize.h
index d43bb7960..4c6a57b34 100644
--- a/source/slang/slang-serialize.h
+++ b/source/slang/slang-serialize.h
@@ -2,7 +2,7 @@
#ifndef SLANG_SERIALIZE_H
#define SLANG_SERIALIZE_H
-#include <type_traits>
+//#include <type_traits>
#include "../core/slang-riff.h"
#include "../core/slang-byte-encode-util.h"
@@ -283,22 +283,6 @@ enum class SerialTypeKind : uint8_t
};
typedef uint16_t SerialSubType;
-enum class RefObjectSerialSubType
-{
- Invalid, ///< Invalid (ie not a known RefObject type)
- LookupResultItem_Breadcrumb,
-
- // TODO(JS):
- // ! We don't want to serialize these types.
- // We could set a nullptr SerialClass in classes ?
- // Perhaps we need some special SerialClass that indicates we want to always write as 0?
-
- Scope,
- Module,
-
- CountOf,
-};
-
struct SerialInfo
{
enum
@@ -416,6 +400,7 @@ class SerialFilter
{
public:
virtual SerialIndex writePointer(SerialWriter* writer, const NodeBase* ptr) = 0;
+ virtual SerialIndex writePointer(SerialWriter* writer, const RefObject* ptr) = 0;
};
class SerialObjectFactory
@@ -556,6 +541,7 @@ public:
/// Set a the ptr associated with an index.
/// NOTE! That there cannot be a pre-existing setting.
void setPointerIndex(const NodeBase* ptr, SerialIndex index);
+ void setPointerIndex(const RefObject* ptr, SerialIndex index);
/// Get the entries table holding how each index maps to an entry
const List<SerialInfo::Entry*>& getEntries() const { return m_entries; }
@@ -641,6 +627,14 @@ struct SerialFieldType
/* Describes a field in a SerialClass. */
struct SerialField
{
+ /// Returns a suitable ptr for use in make.
+ /// NOTE! Sets to 1 so it's constant and not 0 (and so nullptr)
+ template <typename T>
+ static T* getPtr() { return (T*)1; }
+
+ template <typename T>
+ static SerialField make(const char* name, T* in);
+
const char* name; ///< The name of the field
const SerialFieldType* type; ///< The type of the field
uint32_t nativeOffset; ///< Offset to field from base of type
@@ -704,10 +698,6 @@ public:
/// Ctor
SerialClasses();
- static SlangResult create(RefPtr<SerialClasses>& out);
-
- static RefObjectSerialSubType getSubType(const RefObject* obj);
-
protected:
SerialClass* _createSerialClass(const SerialClass* cls);
@@ -730,6 +720,22 @@ struct SerialGetFieldType
}
};
+// !!!!!!!!!!!!!!!!!!!!! SerialGetFieldType<T> !!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+template <typename T>
+/* static */SerialField SerialField::make(const char* name, T* in)
+{
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(in);
+
+ SerialField field;
+ field.name = name;
+ field.type = SerialGetFieldType<T>::getFieldType();
+ // This only works because we in is an offset from 1
+ field.nativeOffset = uint32_t(size_t(ptr) - 1);
+ field.serialOffset = 0;
+ return field;
+}
+
// !!!!!!!!!!!!!!!!!!!!! Convenience functions !!!!!!!!!!!!!!!!!!!!!!!!!!!
template <typename NATIVE_TYPE, typename SERIAL_TYPE>
diff --git a/source/slang/slang-value-reflect.cpp b/source/slang/slang-value-reflect.cpp
new file mode 100644
index 000000000..9a7f1feb3
--- /dev/null
+++ b/source/slang/slang-value-reflect.cpp
@@ -0,0 +1,8 @@
+#include "../../slang.h"
+
+#include "slang-value-reflect.h"
+
+namespace Slang
+{
+
+} // namespace Slang
diff --git a/source/slang/slang-value-reflect.h b/source/slang/slang-value-reflect.h
new file mode 100644
index 000000000..4d6ec5582
--- /dev/null
+++ b/source/slang/slang-value-reflect.h
@@ -0,0 +1,6 @@
+// slang-value-reflect.h
+
+#ifndef SLANG_VALUE_REFLECT_H
+#define SLANG_VALUE_REFLECT_H
+
+#endif // SLANG_VALUE_REFLECT_H
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index 7dafd3823..ec3066778 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -281,10 +281,15 @@
<ClInclude Include="slang-preprocessor.h" />
<ClInclude Include="slang-profile-defs.h" />
<ClInclude Include="slang-profile.h" />
+ <ClInclude Include="slang-ref-object-generated-macro.h" />
+ <ClInclude Include="slang-ref-object-generated.h" />
+ <ClInclude Include="slang-ref-object-reflect.h" />
<ClInclude Include="slang-reflection.h" />
<ClInclude Include="slang-repro.h" />
+ <ClInclude Include="slang-serialize-ast-type-info.h" />
<ClInclude Include="slang-serialize-ast.h" />
<ClInclude Include="slang-serialize-container.h" />
+ <ClInclude Include="slang-serialize-factory.h" />
<ClInclude Include="slang-serialize-ir-types.h" />
<ClInclude Include="slang-serialize-ir.h" />
<ClInclude Include="slang-serialize-misc-type-info.h" />
@@ -299,6 +304,9 @@
<ClInclude Include="slang-token.h" />
<ClInclude Include="slang-type-layout.h" />
<ClInclude Include="slang-type-system-shared.h" />
+ <ClInclude Include="slang-value-generated-macro.h" />
+ <ClInclude Include="slang-value-generated.h" />
+ <ClInclude Include="slang-value-reflect.h" />
<ClInclude Include="slang-visitor.h" />
</ItemGroup>
<ItemGroup>
@@ -398,10 +406,12 @@
<ClCompile Include="slang-parser.cpp" />
<ClCompile Include="slang-preprocessor.cpp" />
<ClCompile Include="slang-profile.cpp" />
+ <ClCompile Include="slang-ref-object-reflect.cpp" />
<ClCompile Include="slang-reflection.cpp" />
<ClCompile Include="slang-repro.cpp" />
<ClCompile Include="slang-serialize-ast.cpp" />
<ClCompile Include="slang-serialize-container.cpp" />
+ <ClCompile Include="slang-serialize-factory.cpp" />
<ClCompile Include="slang-serialize-ir-types.cpp" />
<ClCompile Include="slang-serialize-ir.cpp" />
<ClCompile Include="slang-serialize-reflection.cpp" />
@@ -414,6 +424,7 @@
<ClCompile Include="slang-token.cpp" />
<ClCompile Include="slang-type-layout.cpp" />
<ClCompile Include="slang-type-system-shared.cpp" />
+ <ClCompile Include="slang-value-reflect.cpp" />
<ClCompile Include="slang.cpp" />
</ItemGroup>
<ItemGroup>
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index be81a48c2..d69ff3059 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -294,18 +294,33 @@
<ClInclude Include="slang-profile.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-ref-object-generated-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-generated.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-reflect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-reflection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="slang-repro.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-serialize-ast-type-info.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-serialize-ast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="slang-serialize-container.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-serialize-factory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-serialize-ir-types.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -348,6 +363,15 @@
<ClInclude Include="slang-type-system-shared.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-value-generated-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-value-generated.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-value-reflect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-visitor.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -641,6 +665,9 @@
<ClCompile Include="slang-profile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-ref-object-reflect.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-reflection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -653,6 +680,9 @@
<ClCompile Include="slang-serialize-container.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-serialize-factory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-serialize-ir-types.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -689,6 +719,9 @@
<ClCompile Include="slang-type-system-shared.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-value-reflect.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang.cpp">
<Filter>Source Files</Filter>
</ClCompile>