summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ast-builder.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-05-28 14:01:51 -0400
committerGitHub <noreply@github.com>2020-05-28 14:01:51 -0400
commitc2d31347ea06c768045e7c503ef0188e0e5356de (patch)
tree1a4ee67aafca0a709ae691104023431bb6829825 /source/slang/slang-ast-builder.cpp
parente5d0f3360f44a4cdd2390e7817db17bb3cc0dd04 (diff)
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.
Diffstat (limited to 'source/slang/slang-ast-builder.cpp')
-rw-r--r--source/slang/slang-ast-builder.cpp225
1 files changed, 225 insertions, 0 deletions
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 <assert.h>
+
+#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> astBuilder(new ASTBuilder);
+
+ astBuilder->m_sharedASTBuilder = this;
+
+ memset(m_builtinTypes, 0, sizeof(m_builtinTypes));
+
+ m_errorType = m_astBuilder->create<ErrorType>();
+ m_initializerListType = m_astBuilder->create<InitializerListType>();
+ m_overloadedType = m_astBuilder->create<OverloadGroupType>();
+
+ 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<RefObject> SharedASTBuilder::findSyntaxClass(const UnownedStringSlice& slice)
+{
+ const ReflectClassInfo* typeInfo;
+ if (m_sliceToTypeMap.TryGetValue(slice, typeInfo))
+ {
+ return SyntaxClass<RefObject>(typeInfo);
+ }
+ return SyntaxClass<RefObject>();
+}
+
+const ReflectClassInfo* SharedASTBuilder::findClassInfo(Name* name)
+{
+ const ReflectClassInfo* typeInfo;
+ return m_nameToTypeMap.TryGetValue(name, typeInfo) ? typeInfo : nullptr;
+}
+
+SyntaxClass<RefObject> SharedASTBuilder::findSyntaxClass(Name* name)
+{
+ const ReflectClassInfo* typeInfo;
+ if (m_nameToTypeMap.TryGetValue(name, typeInfo))
+ {
+ return SyntaxClass<RefObject>(typeInfo);
+ }
+ return SyntaxClass<RefObject>();
+}
+
+Type* SharedASTBuilder::getStringType()
+{
+ if (!m_stringType)
+ {
+ auto stringTypeDecl = findMagicDecl("StringType");
+ m_stringType = DeclRefType::create(m_astBuilder, makeDeclRef<Decl>(stringTypeDecl));
+ }
+ return m_stringType;
+}
+
+Type* SharedASTBuilder::getEnumTypeType()
+{
+ if (!m_enumTypeType)
+ {
+ auto enumTypeTypeDecl = findMagicDecl("EnumTypeType");
+ m_enumTypeType = DeclRefType::create(m_astBuilder, makeDeclRef<Decl>(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> decl, RefPtr<BuiltinTypeModifier> modifier)
+{
+ auto type = DeclRefType::create(m_astBuilder, DeclRef<Decl>(decl.Ptr(), nullptr));
+ m_builtinTypes[Index(modifier->tag)] = type;
+}
+
+void SharedASTBuilder::registerMagicDecl(RefPtr<Decl> decl, RefPtr<MagicTypeModifier> 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<GenericDecl>(decl->parentDecl))
+ declToRegister = genericDecl;
+
+ m_magicDecls[modifier->name] = declToRegister.Ptr();
+}
+
+RefPtr<Decl> 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<PtrType> ASTBuilder::getPtrType( RefPtr<Type> valueType)
+{
+ return getPtrType(valueType, "PtrType").dynamicCast<PtrType>();
+}
+
+// Construct the type `Out<valueType>`
+RefPtr<OutType> ASTBuilder::getOutType(RefPtr<Type> valueType)
+{
+ return getPtrType(valueType, "OutType").dynamicCast<OutType>();
+}
+
+RefPtr<InOutType> ASTBuilder::getInOutType(RefPtr<Type> valueType)
+{
+ return getPtrType(valueType, "InOutType").dynamicCast<InOutType>();
+}
+
+RefPtr<RefType> ASTBuilder::getRefType(RefPtr<Type> valueType)
+{
+ return getPtrType(valueType, "RefType").dynamicCast<RefType>();
+}
+
+RefPtr<PtrTypeBase> ASTBuilder::getPtrType(RefPtr<Type> valueType, char const* ptrTypeName)
+{
+ auto genericDecl = m_sharedASTBuilder->findMagicDecl(ptrTypeName).dynamicCast<GenericDecl>();
+ return getPtrType(valueType, genericDecl);
+}
+
+RefPtr<PtrTypeBase> ASTBuilder::getPtrType(RefPtr<Type> valueType, GenericDecl* genericDecl)
+{
+ auto typeDecl = genericDecl->inner;
+
+ auto substitutions = create<GenericSubstitution>();
+ substitutions->genericDecl = genericDecl;
+ substitutions->args.add(valueType);
+
+ auto declRef = DeclRef<Decl>(typeDecl.Ptr(), substitutions);
+ auto rsType = DeclRefType::create(this, declRef);
+ return as<PtrTypeBase>(rsType);
+}
+
+RefPtr<ArrayExpressionType> ASTBuilder::getArrayType(Type* elementType, IntVal* elementCount)
+{
+ RefPtr<ArrayExpressionType> arrayType = create<ArrayExpressionType>();
+ arrayType->baseType = elementType;
+ arrayType->arrayLength = elementCount;
+ return arrayType;
+}
+
+RefPtr<VectorExpressionType> ASTBuilder::getVectorType(
+ RefPtr<Type> elementType,
+ RefPtr<IntVal> elementCount)
+{
+ auto vectorGenericDecl = m_sharedASTBuilder->findMagicDecl("Vector").as<GenericDecl>();
+
+ auto vectorTypeDecl = vectorGenericDecl->inner;
+
+ auto substitutions = new GenericSubstitution();
+ substitutions->genericDecl = vectorGenericDecl.Ptr();
+ substitutions->args.add(elementType);
+ substitutions->args.add(elementCount);
+
+ auto declRef = DeclRef<Decl>(vectorTypeDecl.Ptr(), substitutions);
+
+ return DeclRefType::create(this, declRef).as<VectorExpressionType>();
+}
+
+RefPtr<TypeType> ASTBuilder::getTypeType(Type* type)
+{
+ return create<TypeType>(type);
+}
+
+
+} // namespace Slang