From c2d31347ea06c768045e7c503ef0188e0e5356de Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 28 May 2020 14:01:51 -0400 Subject: WIP: ASTBuilder (#1358) * Compiles. * Small tidy up around session/ASTBuilder. * Tests are now passing. * Fix Visual Studio project. * Fix using new X to use builder when protectedness of Ctor is not enough. Substitute->substitute * Add some missing ast nodes created outside of ASTBuilder. * Compile time check that ASTBuilder is making an AST type. * Moced findClasInfo and findSyntaxClass (essentially the same thing) to SharedASTBuilder from Session. --- source/slang/slang-ast-builder.cpp | 225 +++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 source/slang/slang-ast-builder.cpp (limited to 'source/slang/slang-ast-builder.cpp') diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp new file mode 100644 index 000000000..7e40e52ec --- /dev/null +++ b/source/slang/slang-ast-builder.cpp @@ -0,0 +1,225 @@ +// slang-ast-builder.cpp +#include "slang-ast-builder.h" +#include + +#include "slang-compiler.h" + +namespace Slang { + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SharedASTBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +SharedASTBuilder::SharedASTBuilder() +{ +} + + +void SharedASTBuilder::init(Session* session) +{ + m_namePool = session->getNamePool(); + + // Save the associated session + m_session = session; + + // We just want as a place to store allocations of shared types + RefPtr astBuilder(new ASTBuilder); + + astBuilder->m_sharedASTBuilder = this; + + memset(m_builtinTypes, 0, sizeof(m_builtinTypes)); + + m_errorType = m_astBuilder->create(); + m_initializerListType = m_astBuilder->create(); + m_overloadedType = m_astBuilder->create(); + + m_astBuilder = astBuilder.detach(); + + // We can just iterate over the class pointers. + // NOTE! That this adds the names of the abstract classes too(!) + for (Index i = 0; i < Index(ASTNodeType::CountOf); ++i) + { + const ReflectClassInfo* info = ReflectClassInfo::getInfo(ASTNodeType(i)); + if (info) + { + m_sliceToTypeMap.Add(UnownedStringSlice(info->m_name), info); + Name* name = m_namePool->getName(String(info->m_name)); + m_nameToTypeMap.Add(name, info); + } + } +} + +const ReflectClassInfo* SharedASTBuilder::findClassInfo(const UnownedStringSlice& slice) +{ + const ReflectClassInfo* typeInfo; + return m_sliceToTypeMap.TryGetValue(slice, typeInfo) ? typeInfo : nullptr; +} + +SyntaxClass SharedASTBuilder::findSyntaxClass(const UnownedStringSlice& slice) +{ + const ReflectClassInfo* typeInfo; + if (m_sliceToTypeMap.TryGetValue(slice, typeInfo)) + { + return SyntaxClass(typeInfo); + } + return SyntaxClass(); +} + +const ReflectClassInfo* SharedASTBuilder::findClassInfo(Name* name) +{ + const ReflectClassInfo* typeInfo; + return m_nameToTypeMap.TryGetValue(name, typeInfo) ? typeInfo : nullptr; +} + +SyntaxClass SharedASTBuilder::findSyntaxClass(Name* name) +{ + const ReflectClassInfo* typeInfo; + if (m_nameToTypeMap.TryGetValue(name, typeInfo)) + { + return SyntaxClass(typeInfo); + } + return SyntaxClass(); +} + +Type* SharedASTBuilder::getStringType() +{ + if (!m_stringType) + { + auto stringTypeDecl = findMagicDecl("StringType"); + m_stringType = DeclRefType::create(m_astBuilder, makeDeclRef(stringTypeDecl)); + } + return m_stringType; +} + +Type* SharedASTBuilder::getEnumTypeType() +{ + if (!m_enumTypeType) + { + auto enumTypeTypeDecl = findMagicDecl("EnumTypeType"); + m_enumTypeType = DeclRefType::create(m_astBuilder, makeDeclRef(enumTypeTypeDecl)); + } + return m_enumTypeType; +} + +SharedASTBuilder::~SharedASTBuilder() +{ + // Release built in types.. + for (Index i = 0; i < SLANG_COUNT_OF(m_builtinTypes); ++i) + { + m_builtinTypes[i].setNull(); + } + + if (m_astBuilder) + { + m_astBuilder->releaseReference(); + } +} + +void SharedASTBuilder::registerBuiltinDecl(RefPtr decl, RefPtr modifier) +{ + auto type = DeclRefType::create(m_astBuilder, DeclRef(decl.Ptr(), nullptr)); + m_builtinTypes[Index(modifier->tag)] = type; +} + +void SharedASTBuilder::registerMagicDecl(RefPtr decl, RefPtr modifier) +{ + // In some cases the modifier will have been applied to the + // "inner" declaration of a `GenericDecl`, but what we + // actually want to register is the generic itself. + // + auto declToRegister = decl; + if (auto genericDecl = as(decl->parentDecl)) + declToRegister = genericDecl; + + m_magicDecls[modifier->name] = declToRegister.Ptr(); +} + +RefPtr SharedASTBuilder::findMagicDecl(const String& name) +{ + return m_magicDecls[name].GetValue(); +} + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +ASTBuilder::ASTBuilder(SharedASTBuilder* sharedASTBuilder): + m_sharedASTBuilder(sharedASTBuilder) +{ + SLANG_ASSERT(sharedASTBuilder); +} + +ASTBuilder::ASTBuilder(): + m_sharedASTBuilder(nullptr) +{ +} + +RefPtr ASTBuilder::getPtrType( RefPtr valueType) +{ + return getPtrType(valueType, "PtrType").dynamicCast(); +} + +// Construct the type `Out` +RefPtr ASTBuilder::getOutType(RefPtr valueType) +{ + return getPtrType(valueType, "OutType").dynamicCast(); +} + +RefPtr ASTBuilder::getInOutType(RefPtr valueType) +{ + return getPtrType(valueType, "InOutType").dynamicCast(); +} + +RefPtr ASTBuilder::getRefType(RefPtr valueType) +{ + return getPtrType(valueType, "RefType").dynamicCast(); +} + +RefPtr ASTBuilder::getPtrType(RefPtr valueType, char const* ptrTypeName) +{ + auto genericDecl = m_sharedASTBuilder->findMagicDecl(ptrTypeName).dynamicCast(); + return getPtrType(valueType, genericDecl); +} + +RefPtr ASTBuilder::getPtrType(RefPtr valueType, GenericDecl* genericDecl) +{ + auto typeDecl = genericDecl->inner; + + auto substitutions = create(); + substitutions->genericDecl = genericDecl; + substitutions->args.add(valueType); + + auto declRef = DeclRef(typeDecl.Ptr(), substitutions); + auto rsType = DeclRefType::create(this, declRef); + return as(rsType); +} + +RefPtr ASTBuilder::getArrayType(Type* elementType, IntVal* elementCount) +{ + RefPtr arrayType = create(); + arrayType->baseType = elementType; + arrayType->arrayLength = elementCount; + return arrayType; +} + +RefPtr ASTBuilder::getVectorType( + RefPtr elementType, + RefPtr elementCount) +{ + auto vectorGenericDecl = m_sharedASTBuilder->findMagicDecl("Vector").as(); + + auto vectorTypeDecl = vectorGenericDecl->inner; + + auto substitutions = new GenericSubstitution(); + substitutions->genericDecl = vectorGenericDecl.Ptr(); + substitutions->args.add(elementType); + substitutions->args.add(elementCount); + + auto declRef = DeclRef(vectorTypeDecl.Ptr(), substitutions); + + return DeclRefType::create(this, declRef).as(); +} + +RefPtr ASTBuilder::getTypeType(Type* type) +{ + return create(type); +} + + +} // namespace Slang -- cgit v1.2.3