diff options
Diffstat (limited to 'source/slang/slang-serialize-ast.cpp')
| -rw-r--r-- | source/slang/slang-serialize-ast.cpp | 558 |
1 files changed, 10 insertions, 548 deletions
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; |
