diff options
Diffstat (limited to 'source')
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> |
