summaryrefslogtreecommitdiffstats
path: root/source/slang/syntax.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 17:20:37 -0400
committerGitHub <noreply@github.com>2019-05-31 17:20:37 -0400
commit6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f (patch)
tree5a23cb47782e9e2a77762c90dd35da1005eba8d0 /source/slang/syntax.h
parentb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (diff)
Use slang- prefix on slang compiler and core source (#973)
* Prefixing source files in source/slang with slang- * Prefix source in source/slang with slang- prefix. * Rename core source files with slang- prefix. * Update project files. * Fix problems from automatic merge.
Diffstat (limited to 'source/slang/syntax.h')
-rw-r--r--source/slang/syntax.h1419
1 files changed, 0 insertions, 1419 deletions
diff --git a/source/slang/syntax.h b/source/slang/syntax.h
deleted file mode 100644
index aa3944d0a..000000000
--- a/source/slang/syntax.h
+++ /dev/null
@@ -1,1419 +0,0 @@
-#ifndef SLANG_SYNTAX_H
-#define SLANG_SYNTAX_H
-
-#include "../core/basic.h"
-#include "ir.h"
-#include "lexer.h"
-#include "profile.h"
-#include "type-system-shared.h"
-#include "../../slang.h"
-
-#include <assert.h>
-
-namespace Slang
-{
- class Module;
- class Name;
- class Session;
- class Substitutions;
- class SyntaxVisitor;
- class FuncDecl;
- class Layout;
-
- struct IExprVisitor;
- struct IDeclVisitor;
- struct IModifierVisitor;
- struct IStmtVisitor;
- struct ITypeVisitor;
- struct IValVisitor;
-
- class Parser;
- class SyntaxNode;
-
- typedef RefPtr<RefObject> (*SyntaxParseCallback)(Parser* parser, void* userData);
-
- typedef unsigned int ConversionCost;
- enum : ConversionCost
- {
- // No conversion at all
- kConversionCost_None = 0,
-
- // Conversion from a buffer to the type it carries needs to add a minimal
- // extra cost, just so we can distinguish an overload on `ConstantBuffer<Foo>`
- // from one on `Foo`
- kConversionCost_ImplicitDereference = 10,
-
- // Conversions based on explicit sub-typing relationships are the cheapest
- //
- // TODO(tfoley): We will eventually need a discipline for ranking
- // when two up-casts are comparable.
- kConversionCost_CastToInterface = 50,
-
- // Conversion that is lossless and keeps the "kind" of the value the same
- kConversionCost_RankPromotion = 150,
-
- // Conversions that are lossless, but change "kind"
- kConversionCost_UnsignedToSignedPromotion = 200,
-
- // Conversion from signed->unsigned integer of same or greater size
- kConversionCost_SignedToUnsignedConversion = 300,
-
- // Cost of converting an integer to a floating-point type
- kConversionCost_IntegerToFloatConversion = 400,
-
- // Default case (usable for user-defined conversions)
- kConversionCost_Default = 500,
-
- // Catch-all for conversions that should be discouraged
- // (i.e., that really shouldn't be made implicitly)
- //
- // TODO: make these conversions not be allowed implicitly in "Slang mode"
- kConversionCost_GeneralConversion = 900,
-
- // This is the cost of an explicit conversion, which should
- // not actually be performed.
- kConversionCost_Explicit = 90000,
-
- // Additional conversion cost to add when promoting from a scalar to
- // a vector (this will be added to the cost, if any, of converting
- // the element type of the vector)
- kConversionCost_ScalarToVector = 1,
-
- // Conversion is impossible
- kConversionCost_Impossible = 0xFFFFFFFF,
- };
-
- enum class ImageFormat
- {
-#define FORMAT(NAME) NAME,
-#include "image-format-defs.h"
- };
-
- bool findImageFormatByName(char const* name, ImageFormat* outFormat);
- char const* getGLSLNameForImageFormat(ImageFormat format);
-
- // TODO(tfoley): We should ditch this enumeration
- // and just use the IR opcodes that represent these
- // types directly. The one major complication there
- // is that the order of the enum values currently
- // matters, since it determines promotion rank.
- // We either need to keep that restriction, or
- // look up promotion rank by some other means.
- //
-
- class Decl;
- class Val;
-
- // Forward-declare all syntax classes
-#define SYNTAX_CLASS(NAME, BASE, ...) class NAME;
-#include "object-meta-begin.h"
-#include "syntax-defs.h"
-#include "object-meta-end.h"
-
- // Helper type for pairing up a name and the location where it appeared
- struct NameLoc
- {
- Name* name;
- SourceLoc loc;
-
- NameLoc()
- : name(nullptr)
- {}
-
- explicit NameLoc(Name* name)
- : name(name)
- {}
-
-
- NameLoc(Name* name, SourceLoc loc)
- : name(name)
- , loc(loc)
- {}
-
- NameLoc(Token const& token)
- : name(token.getNameOrNull())
- , loc(token.getLoc())
- {}
- };
-
- // Helper class for iterating over a list of heap-allocated modifiers
- struct ModifierList
- {
- struct Iterator
- {
- Modifier* current;
-
- Modifier* operator*()
- {
- return current;
- }
-
- void operator++();
-#if 0
- {
- current = current->next.Ptr();
- }
-#endif
-
- bool operator!=(Iterator other)
- {
- return current != other.current;
- };
-
- Iterator()
- : current(nullptr)
- {}
-
- Iterator(Modifier* modifier)
- : current(modifier)
- {}
- };
-
- ModifierList()
- : modifiers(nullptr)
- {}
-
- ModifierList(Modifier* modifiers)
- : modifiers(modifiers)
- {}
-
- Iterator begin() { return Iterator(modifiers); }
- Iterator end() { return Iterator(nullptr); }
-
- Modifier* modifiers;
- };
-
- // Helper class for iterating over heap-allocated modifiers
- // of a specific type.
- template<typename T>
- struct FilteredModifierList
- {
- struct Iterator
- {
- Modifier* current;
-
- T* operator*()
- {
- return (T*)current;
- }
-
- void operator++();
- #if 0
- {
- current = Adjust(current->next.Ptr());
- }
- #endif
-
- bool operator!=(Iterator other)
- {
- return current != other.current;
- };
-
- Iterator()
- : current(nullptr)
- {}
-
- Iterator(Modifier* modifier)
- : current(modifier)
- {}
- };
-
- FilteredModifierList()
- : modifiers(nullptr)
- {}
-
- FilteredModifierList(Modifier* modifiers)
- : modifiers(Adjust(modifiers))
- {}
-
- Iterator begin() { return Iterator(modifiers); }
- Iterator end() { return Iterator(nullptr); }
-
- static Modifier* Adjust(Modifier* modifier);
- #if 0
- {
- Modifier* m = modifier;
- for (;;)
- {
- if (!m) return m;
- if (dynamicCast<T>(m)) return m;
- m = m->next.Ptr();
- }
- }
- #endif
-
- Modifier* modifiers;
- };
-
- // A set of modifiers attached to a syntax node
- struct Modifiers
- {
- // The first modifier in the linked list of heap-allocated modifiers
- RefPtr<Modifier> first;
-
- template<typename T>
- FilteredModifierList<T> getModifiersOfType() { return FilteredModifierList<T>(first.Ptr()); }
-
- // Find the first modifier of a given type, or return `nullptr` if none is found.
- template<typename T>
- T* findModifier()
- {
- return *getModifiersOfType<T>().begin();
- }
-
- template<typename T>
- bool hasModifier() { return findModifier<T>() != nullptr; }
-
- FilteredModifierList<Modifier>::Iterator begin() { return FilteredModifierList<Modifier>::Iterator(first.Ptr()); }
- FilteredModifierList<Modifier>::Iterator end() { return FilteredModifierList<Modifier>::Iterator(nullptr); }
- };
-
- class NamedExpressionType;
- class GenericDecl;
- class ContainerDecl;
-
- // Try to extract a simple integer value from an `IntVal`.
- // This fill assert-fail if the object doesn't represent a literal value.
- IntegerLiteralValue GetIntVal(RefPtr<IntVal> val);
-
- // Represents how much checking has been applied to a declaration.
- enum class DeclCheckState : uint8_t
- {
- // The declaration has been parsed, but not checked
- Unchecked,
-
- // We are in the process of checking the declaration "header"
- // (those parts of the declaration needed in order to
- // reference it)
- CheckingHeader,
-
- // We are done checking the declaration header.
- CheckedHeader,
-
- // We have checked the declaration fully.
- Checked,
- };
-
- void addModifier(
- RefPtr<ModifiableSyntaxNode> syntax,
- RefPtr<Modifier> modifier);
-
- struct QualType
- {
- RefPtr<Type> type;
- bool IsLeftValue;
-
- QualType()
- : IsLeftValue(false)
- {}
-
- QualType(Type* type)
- : type(type)
- , IsLeftValue(false)
- {}
-
- Type* Ptr() { return type.Ptr(); }
-
- operator Type*() { return type; }
- operator RefPtr<Type>() { return type; }
- RefPtr<Type> operator->() { return type; }
- };
-
- // A reference to a class of syntax node, that can be
- // used to create instances on the fly
- struct SyntaxClassBase
- {
- typedef void* (*CreateFunc)();
-
- // Run-time type representation for syntax nodes
- struct ClassInfo
- {
- // Textual class name, for debugging
- char const* name;
-
- // Base class for runtime queries
- ClassInfo const* baseClass;
-
- // Callback to use when creating instances
- CreateFunc createFunc;
- };
-
- SyntaxClassBase()
- {}
-
- SyntaxClassBase(ClassInfo const* classInfoIn)
- : classInfo(classInfoIn)
- {}
-
- void* createInstanceImpl() const
- {
- auto ci = classInfo;
- if (!ci) return nullptr;
-
- auto cf = ci->createFunc;
- if (!cf) return nullptr;
-
- return cf();
- }
-
- bool isSubClassOfImpl(SyntaxClassBase const& super) const;
-
- ClassInfo const* classInfo = nullptr;
-
- template<typename T>
- struct Impl
- {
- static void* createFunc();
- static const ClassInfo kClassInfo;
- };
- };
-
- template<typename T>
- struct SyntaxClass : SyntaxClassBase
- {
- SyntaxClass()
- {}
-
- template <typename U>
- SyntaxClass(SyntaxClass<U> const& other,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
- : SyntaxClassBase(other.classInfo)
- {
- }
-
- T* createInstance() const
- {
- return (T*)createInstanceImpl();
- }
-
- SyntaxClass(const ClassInfo* classInfoIn):
- SyntaxClassBase(classInfoIn)
- {}
-
- static SyntaxClass<T> getClass()
- {
- return SyntaxClass<T>(&SyntaxClassBase::Impl<T>::kClassInfo);
- }
-
- template<typename U>
- bool isSubClassOf(SyntaxClass<U> super)
- {
- return isSubClassOfImpl(super);
- }
-
- template<typename U>
- bool isSubClassOf()
- {
- return isSubClassOf(SyntaxClass<U>::getClass());
- }
- };
-
- template<typename T>
- SyntaxClass<T> getClass()
- {
- return SyntaxClass<T>::getClass();
- }
-
- struct SubstitutionSet
- {
- RefPtr<Substitutions> substitutions;
- operator Substitutions*() const
- {
- return substitutions;
- }
-
- SubstitutionSet() {}
- SubstitutionSet(RefPtr<Substitutions> subst)
- : substitutions(subst)
- {
- }
- bool Equals(const SubstitutionSet& substSet) const;
- int GetHashCode() const;
- };
-
- template<typename T>
- struct DeclRef;
-
- // A reference to a declaration, which may include
- // substitutions for generic parameters.
- struct DeclRefBase
- {
- typedef Decl DeclType;
-
- // The underlying declaration
- Decl* decl = nullptr;
- Decl* getDecl() const { return decl; }
-
- // Optionally, a chain of substitutions to perform
- SubstitutionSet substitutions;
-
- DeclRefBase()
- {}
-
- DeclRefBase(Decl* decl)
- :decl(decl)
- {}
-
- DeclRefBase(Decl* decl, SubstitutionSet subst)
- :decl(decl),
- substitutions(subst)
- {}
-
- DeclRefBase(Decl* decl, RefPtr<Substitutions> subst)
- : decl(decl)
- , substitutions(subst)
- {}
-
- // Apply substitutions to a type or declaration
- RefPtr<Type> Substitute(RefPtr<Type> type) const;
-
- DeclRefBase Substitute(DeclRefBase declRef) const;
-
- // Apply substitutions to an expression
- RefPtr<Expr> Substitute(RefPtr<Expr> expr) const;
-
- // Apply substitutions to this declaration reference
- DeclRefBase SubstituteImpl(SubstitutionSet subst, int* ioDiff);
-
- // Returns true if 'as' will return a valid cast
- template <typename T>
- bool is() const { return Slang::as<T>(decl) != nullptr; }
-
- // "dynamic cast" to a more specific declaration reference type
- template<typename T>
- DeclRef<T> as() const;
-
- // Check if this is an equivalent declaration reference to another
- bool Equals(DeclRefBase const& declRef) const;
- bool operator == (const DeclRefBase& other) const
- {
- return Equals(other);
- }
-
- // Convenience accessors for common properties of declarations
- Name* GetName() const;
- SourceLoc getLoc() const;
- DeclRefBase GetParent() const;
-
- int GetHashCode() const;
-
- // Debugging:
- String toString() const;
- };
-
- template<typename T>
- struct DeclRef : DeclRefBase
- {
- typedef T DeclType;
-
- DeclRef()
- {}
-
- DeclRef(T* decl, SubstitutionSet subst)
- : DeclRefBase(decl, subst)
- {}
-
- DeclRef(T* decl, RefPtr<Substitutions> subst)
- : DeclRefBase(decl, SubstitutionSet(subst))
- {}
-
- template <typename U>
- DeclRef(DeclRef<U> const& other,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
- : DeclRefBase(other.decl, other.substitutions)
- {
- }
-
- T* getDecl() const
- {
- return (T*)decl;
- }
-
- operator T*() const
- {
- return getDecl();
- }
-
- //
- static DeclRef<T> unsafeInit(DeclRefBase const& declRef)
- {
- return DeclRef<T>((T*) declRef.decl, declRef.substitutions);
- }
-
- RefPtr<Type> Substitute(RefPtr<Type> type) const
- {
- return DeclRefBase::Substitute(type);
- }
- RefPtr<Expr> Substitute(RefPtr<Expr> expr) const
- {
- return DeclRefBase::Substitute(expr);
- }
-
- // Apply substitutions to a type or declaration
- template<typename U>
- DeclRef<U> Substitute(DeclRef<U> declRef) const
- {
- return DeclRef<U>::unsafeInit(DeclRefBase::Substitute(declRef));
- }
-
- // Apply substitutions to this declaration reference
- DeclRef<T> SubstituteImpl(SubstitutionSet subst, int* ioDiff)
- {
- return DeclRef<T>::unsafeInit(DeclRefBase::SubstituteImpl(subst, ioDiff));
- }
-
- DeclRef<ContainerDecl> GetParent() const
- {
- return DeclRef<ContainerDecl>::unsafeInit(DeclRefBase::GetParent());
- }
- };
-
- template<typename T>
- DeclRef<T> DeclRefBase::as() const
- {
- DeclRef<T> result;
- result.decl = Slang::as<T>(decl);
- result.substitutions = substitutions;
- return result;
- }
-
- template<typename T>
- inline DeclRef<T> makeDeclRef(T* decl)
- {
- return DeclRef<T>(decl, nullptr);
- }
-
- template<typename T>
- struct FilteredMemberList
- {
- typedef RefPtr<Decl> Element;
-
- FilteredMemberList()
- : m_begin(nullptr)
- , m_end(nullptr)
- {}
-
- explicit FilteredMemberList(
- List<Element> const& list)
- : m_begin(adjust(list.begin(), list.end()))
- , m_end(list.end())
- {}
-
- struct Iterator
- {
- Element* m_cursor;
- Element* m_end;
-
- bool operator!=(Iterator const& other)
- {
- return m_cursor != other.m_cursor;
- }
-
- void operator++()
- {
- m_cursor = adjust(m_cursor + 1, m_end);
- }
-
- RefPtr<T>& operator*()
- {
- return *(RefPtr<T>*)m_cursor;
- }
- };
-
- Iterator begin()
- {
- Iterator iter = { m_begin, m_end };
- return iter;
- }
-
- Iterator end()
- {
- Iterator iter = { m_end, m_end };
- return iter;
- }
-
- static Element* adjust(Element* cursor, Element* end)
- {
- while (cursor != end)
- {
- if (as<T>(*cursor))
- return cursor;
- cursor++;
- }
- return cursor;
- }
-
- // TODO(tfoley): It is ugly to have these.
- // We should probably fix the call sites instead.
- RefPtr<T>& getFirst() { return *begin(); }
- Index getCount()
- {
- Index count = 0;
- for (auto iter : (*this))
- {
- (void)iter;
- count++;
- }
- return count;
- }
-
- List<RefPtr<T>> toArray()
- {
- List<RefPtr<T>> result;
- for (auto element : (*this))
- {
- result.add(element);
- }
- return result;
- }
-
- Element* m_begin;
- Element* m_end;
- };
-
- struct TransparentMemberInfo
- {
- // The declaration of the transparent member
- Decl* decl;
- };
-
- template<typename T>
- struct FilteredMemberRefList
- {
- List<RefPtr<Decl>> const& decls;
- SubstitutionSet substitutions;
-
- FilteredMemberRefList(
- List<RefPtr<Decl>> const& decls,
- SubstitutionSet substitutions)
- : decls(decls)
- , substitutions(substitutions)
- {}
-
- int Count() const
- {
- int count = 0;
- for (auto d : *this)
- count++;
- return count;
- }
-
- List<DeclRef<T>> ToArray() const
- {
- List<DeclRef<T>> result;
- for (auto d : *this)
- result.add(d);
- return result;
- }
-
- struct Iterator
- {
- FilteredMemberRefList const* list;
- RefPtr<Decl>* ptr;
- RefPtr<Decl>* end;
-
- Iterator() : list(nullptr), ptr(nullptr) {}
- Iterator(
- FilteredMemberRefList const* list,
- RefPtr<Decl>* ptr,
- RefPtr<Decl>* end)
- : list(list)
- , ptr(ptr)
- , end(end)
- {}
-
- bool operator!=(Iterator other)
- {
- return ptr != other.ptr;
- }
-
- void operator++()
- {
- ptr = list->Adjust(ptr + 1, end);
- }
-
- DeclRef<T> operator*()
- {
- return DeclRef<T>((T*) ptr->Ptr(), list->substitutions);
- }
- };
-
- Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); }
- Iterator end() const { return Iterator(this, decls.end(), decls.end()); }
-
- RefPtr<Decl>* Adjust(RefPtr<Decl>* ptr, RefPtr<Decl>* end) const
- {
- for (; ptr != end; ptr++)
- {
- if (ptr->is<T>())
- {
- return ptr;
- }
- }
- return end;
- }
- };
-
- //
- // type Expressions
- //
-
- // A "type expression" is a term that we expect to resolve to a type during checking.
- // We store both the original syntax and the resolved type here.
- struct TypeExp
- {
- TypeExp() {}
- TypeExp(TypeExp const& other)
- : exp(other.exp)
- , type(other.type)
- {}
- explicit TypeExp(RefPtr<Expr> exp)
- : exp(exp)
- {}
- explicit TypeExp(RefPtr<Type> type)
- : type(type)
- {}
- TypeExp(RefPtr<Expr> exp, RefPtr<Type> type)
- : exp(exp)
- , type(type)
- {}
-
- RefPtr<Expr> exp;
- RefPtr<Type> type;
-
- bool Equals(Type* other);
-#if 0
- {
- return type->Equals(other);
- }
-#endif
- bool Equals(RefPtr<Type> other);
-#if 0
- {
- return type->Equals(other.Ptr());
- }
-#endif
- Type* Ptr() { return type.Ptr(); }
- operator Type*()
- {
- return type;
- }
- Type* operator->() { return Ptr(); }
-
- TypeExp Accept(SyntaxVisitor* visitor);
- };
-
-
-
- struct Scope : public RefObject
- {
- // The parent of this scope (where lookup should go if nothing is found locally)
- RefPtr<Scope> parent;
-
- // The next sibling of this scope (a peer for lookup)
- RefPtr<Scope> nextSibling;
-
- // The container to use for lookup
- //
- // Note(tfoley): This is kept as an unowned pointer
- // so that a scope can't keep parts of the AST alive,
- // but the opposite it allowed.
- ContainerDecl* containerDecl;
- };
-
- // Masks to be applied when lookup up declarations
- enum class LookupMask : uint8_t
- {
- type = 0x1,
- Function = 0x2,
- Value = 0x4,
- Attribute = 0x8,
-
- Default = type | Function | Value,
- };
-
- // Represents one item found during lookup
- struct LookupResultItem
- {
- // 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
- // appropriate AST nodes for all the steps.
- //
- // We build up a list of these "breadcrumbs" while doing
- // lookup, and store them alongside each item found.
- //
- // As an example, suppose we have an HLSL `cbuffer` declaration:
- //
- // cbuffer C { float4 f; }
- //
- // This is syntax sugar for a global-scope variable of
- // type `ConstantBuffer<T>` where `T` is a `struct` containing
- // all the members:
- //
- // struct Anon0 { float4 f; };
- // __transparent ConstantBuffer<Anon0> anon1;
- //
- // The `__transparent` modifier there captures the fact that
- // when somebody writes `f` in their code, they expect it to
- // "see through" the `cbuffer` declaration (or the global variable,
- // in this case) and find the member inside.
- //
- // But when the user writes `f` we can't just create a simple
- // `VarExpr` that refers directly to that field, because that
- // doesn't actually reflect the required steps in a way that
- // code generation can use.
- //
- // Instead we need to construct an expression like `(*anon1).f`,
- // where there is are two additional steps in the process:
- //
- // 1. We needed to dereference the pointer-like type `ConstantBuffer<Anon0>`
- // to get at a value of type `Anon0`
- // 2. We needed to access a sub-field of the aggregate type `Anon0`
- //
- // We *could* just create these full-formed expressions during
- // lookup, but this might mean creating a large number of
- // AST nodes in cases where the user calls an overloaded function.
- // At the very least we'd rather not heap-allocate in the common
- // case where no "extra" steps need to be performed to get to
- // the declarations.
- //
- // This is where "breadcrumbs" come in. A breadcrumb represents
- // an extra "step" that must be performed to turn a declaration
- // found by lookup into a valid expression to splice into the
- // AST. Most of the time lookup result items don't have any
- // breadcrumbs, so that no extra heap allocation takes place.
- // When an item does have breadcrumbs, and it is chosen as
- // 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.
- Constraint,
-
- // 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, is the `this` parameter
- // mutable or not?
- enum class ThisParameterMode : uint8_t
- {
- Default,
- Mutating,
- };
- 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;
-
- // The next implicit step that the lookup process took to
- // arrive at a final value.
- RefPtr<Breadcrumb> next;
-
- Breadcrumb(
- Kind kind,
- DeclRef<Decl> declRef,
- RefPtr<Breadcrumb> next,
- ThisParameterMode thisParameterMode = ThisParameterMode::Default)
- : kind(kind)
- , thisParameterMode(thisParameterMode)
- , declRef(declRef)
- , next(next)
- {}
- };
-
- // A properly-specialized reference to the declaration that was found.
- DeclRef<Decl> declRef;
-
- // Any breadcrumbs needed in order to turn that declaration
- // reference into a well-formed expression.
- //
- // This is unused in the simple case where a declaration
- // is being referenced directly (rather than through
- // transparent members).
- RefPtr<Breadcrumb> breadcrumbs;
-
- LookupResultItem() = default;
- explicit LookupResultItem(DeclRef<Decl> declRef)
- : declRef(declRef)
- {}
- LookupResultItem(DeclRef<Decl> declRef, RefPtr<Breadcrumb> breadcrumbs)
- : declRef(declRef)
- , breadcrumbs(breadcrumbs)
- {}
- };
-
-
- // Result of looking up a name in some lexical/semantic environment.
- // Can be used to enumerate all the declarations matching that name,
- // in the case where the result is overloaded.
- struct LookupResult
- {
- // The one item that was found, in the smple case
- LookupResultItem item;
-
- // All of the items that were found, in the complex case.
- // Note: if there was no overloading, then this list isn't
- // used at all, to avoid allocation.
- List<LookupResultItem> items;
-
- HashSet<DeclRef<ContainerDecl>> lookedupDecls;
-
- // Was at least one result found?
- bool isValid() const { return item.declRef.getDecl() != nullptr; }
-
- bool isOverloaded() const { return items.getCount() > 1; }
-
- Name* getName() const
- {
- return items.getCount() > 1 ? items[0].declRef.GetName() : item.declRef.GetName();
- }
- LookupResultItem* begin()
- {
- if (isValid())
- {
- if (isOverloaded())
- return items.begin();
- else
- return &item;
- }
- else
- return nullptr;
- }
- LookupResultItem* end()
- {
- if (isValid())
- {
- if (isOverloaded())
- return items.end();
- else
- return &item + 1;
- }
- else
- return nullptr;
- }
- };
-
- struct SemanticsVisitor;
-
- struct LookupRequest
- {
- SemanticsVisitor* semantics = nullptr;
- RefPtr<Scope> scope = nullptr;
- RefPtr<Scope> endScope = nullptr;
-
- LookupMask mask = LookupMask::Default;
- };
-
- struct WitnessTable;
-
- // A value that witnesses the satisfaction of an interface
- // requirement by a particular declaration or value.
- struct RequirementWitness
- {
- RequirementWitness()
- : m_flavor(Flavor::none)
- {}
-
- RequirementWitness(DeclRef<Decl> declRef)
- : m_flavor(Flavor::declRef)
- , m_declRef(declRef)
- {}
-
- RequirementWitness(RefPtr<Val> val);
-
- RequirementWitness(RefPtr<WitnessTable> witnessTable);
-
- enum class Flavor
- {
- none,
- declRef,
- val,
- witnessTable,
- };
-
- Flavor getFlavor()
- {
- return m_flavor;
- }
-
- DeclRef<Decl> getDeclRef()
- {
- SLANG_ASSERT(getFlavor() == Flavor::declRef);
- return m_declRef;
- }
-
- RefPtr<Val> getVal()
- {
- SLANG_ASSERT(getFlavor() == Flavor::val);
- return m_obj.as<Val>();
- }
-
- RefPtr<WitnessTable> getWitnessTable();
-
- RequirementWitness specialize(SubstitutionSet const& subst);
-
- Flavor m_flavor;
- DeclRef<Decl> m_declRef;
- RefPtr<RefObject> m_obj;
-
- };
-
- typedef Dictionary<Decl*, RequirementWitness> RequirementDictionary;
-
- struct WitnessTable : RefObject
- {
- RequirementDictionary requirementDictionary;
- };
-
- typedef Dictionary<unsigned int, RefPtr<RefObject>> AttributeArgumentValueDict;
-
- /// Collects information about existential type parameters and their arguments.
- struct ExistentialTypeSlots
- {
- /// For each type parameter, holds the interface/existential type that constrains it.
- List<RefPtr<Type>> paramTypes;
-
- /// An argument for an existential type parameter.
- ///
- /// Comprises a concrete type and a witness for its conformance to the desired
- /// interface/existential type for the corresponding parameter.
- ///
- struct Arg
- {
- RefPtr<Type> type;
- RefPtr<Val> witness;
- };
-
- /// Any arguments provided for the existential type parameters.
- ///
- /// It is possible for `args` to be empty even if `paramTypes` is non-empty;
- /// that situation represents an unspecialized program or entry point.
- ///
- List<Arg> args;
- };
-
-
- // Generate class definition for all syntax classes
-#define SYNTAX_FIELD(TYPE, NAME) TYPE NAME;
-#define FIELD(TYPE, NAME) TYPE NAME;
-#define FIELD_INIT(TYPE, NAME, INIT) TYPE NAME = INIT;
-#define RAW(...) __VA_ARGS__
-#define END_SYNTAX_CLASS() };
-#define SYNTAX_CLASS(NAME, BASE, ...) class NAME : public BASE {public:
-#include "object-meta-begin.h"
-
-#include "syntax-base-defs.h"
-#undef SYNTAX_CLASS
-
-#undef ABSTRACT_SYNTAX_CLASS
-#define ABSTRACT_SYNTAX_CLASS(NAME, BASE, ...) \
- class NAME : public BASE { \
- public: /* ... */
-#define SYNTAX_CLASS(NAME, BASE, ...) \
- class NAME : public BASE { \
- virtual void accept(NAME::Visitor* visitor, void* extra) override; \
- public: virtual SyntaxClass<NodeBase> getClass() override; \
- public: /* ... */
-#include "expr-defs.h"
-#include "decl-defs.h"
-#include "modifier-defs.h"
-#include "stmt-defs.h"
-#include "type-defs.h"
-#include "val-defs.h"
-
-#include "object-meta-end.h"
-
- inline RefPtr<Type> GetSub(DeclRef<GenericTypeConstraintDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->sub.Ptr());
- }
-
- inline RefPtr<Type> GetSup(DeclRef<TypeConstraintDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->getSup().type);
- }
-
- // Note(tfoley): These logically belong to `Type`,
- // but order-of-declaration stuff makes that tricky
- //
- // TODO(tfoley): These should really belong to the compilation context!
- //
- void registerBuiltinDecl(
- Session* session,
- RefPtr<Decl> decl,
- RefPtr<BuiltinTypeModifier> modifier);
- void registerMagicDecl(
- Session* session,
- RefPtr<Decl> decl,
- RefPtr<MagicTypeModifier> modifier);
-
- // Look up a magic declaration by its name
- RefPtr<Decl> findMagicDecl(
- Session* session,
- String const& name);
-
- // Create an instance of a syntax class by name
- SyntaxNodeBase* createInstanceOfSyntaxClassByName(
- String const& name);
-
- // `Val`
-
- inline bool areValsEqual(Val* left, Val* right)
- {
- if(!left || !right) return left == right;
- return left->EqualsVal(right);
- }
-
- //
-
- inline BaseType GetVectorBaseType(VectorExpressionType* vecType)
- {
- auto basicExprType = as<BasicExpressionType>(vecType->elementType);
- return basicExprType->baseType;
- }
-
- inline int GetVectorSize(VectorExpressionType* vecType)
- {
- auto constantVal = as<ConstantIntVal>(vecType->elementCount);
- if (constantVal)
- return (int) constantVal->value;
- // TODO: what to do in this case?
- return 0;
- }
-
- //
- // Declarations
- //
-
- inline ExtensionDecl* GetCandidateExtensions(DeclRef<AggTypeDecl> const& declRef)
- {
- return declRef.getDecl()->candidateExtensions;
- }
-
- inline FilteredMemberRefList<Decl> getMembers(DeclRef<ContainerDecl> const& declRef)
- {
- return FilteredMemberRefList<Decl>(declRef.getDecl()->Members, declRef.substitutions);
- }
-
- template<typename T>
- inline FilteredMemberRefList<T> getMembersOfType(DeclRef<ContainerDecl> const& declRef)
- {
- return FilteredMemberRefList<T>(declRef.getDecl()->Members, declRef.substitutions);
- }
-
- template<typename T>
- inline List<DeclRef<T>> getMembersOfTypeWithExt(DeclRef<ContainerDecl> const& declRef)
- {
- List<DeclRef<T>> rs;
- for (auto d : getMembersOfType<T>(declRef))
- rs.add(d);
- if (auto aggDeclRef = declRef.as<AggTypeDecl>())
- {
- for (auto ext = GetCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension)
- {
- auto extMembers = getMembersOfType<T>(DeclRef<ContainerDecl>(ext, declRef.substitutions));
- for (auto mbr : extMembers)
- rs.add(mbr);
- }
- }
- return rs;
- }
-
- /// The the user-level name for a variable that might be a shader parameter.
- ///
- /// In most cases this is just the name of the variable declaration itself,
- /// but in the specific case of a `cbuffer`, the name that the user thinks
- /// of is really metadata. For example:
- ///
- /// cbuffer C { int x; }
- ///
- /// In this example, error messages relating to the constant buffer should
- /// really use the name `C`, but that isn't the name of the declaration
- /// (it is in practice anonymous, and `C` can be used for a different
- /// declaration in the same file).
- ///
- Name* getReflectionName(VarDeclBase* varDecl);
-
- inline RefPtr<Type> GetType(DeclRef<VarDeclBase> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->type.Ptr());
- }
-
- inline RefPtr<Expr> getInitExpr(DeclRef<VarDeclBase> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->initExpr);
- }
-
- inline RefPtr<Type> getType(DeclRef<EnumCaseDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->type.Ptr());
- }
-
- inline RefPtr<Expr> getTagExpr(DeclRef<EnumCaseDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->tagExpr);
- }
-
- inline RefPtr<Type> GetTargetType(DeclRef<ExtensionDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->targetType.Ptr());
- }
-
- inline FilteredMemberRefList<VarDecl> GetFields(DeclRef<StructDecl> const& declRef)
- {
- return getMembersOfType<VarDecl>(declRef);
- }
-
- inline RefPtr<Type> getBaseType(DeclRef<InheritanceDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->base.type);
- }
-
- inline RefPtr<Type> GetType(DeclRef<TypeDefDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->type.Ptr());
- }
-
- inline RefPtr<Type> GetResultType(DeclRef<CallableDecl> const& declRef)
- {
- return declRef.Substitute(declRef.getDecl()->ReturnType.type.Ptr());
- }
-
- inline FilteredMemberRefList<ParamDecl> GetParameters(DeclRef<CallableDecl> const& declRef)
- {
- return getMembersOfType<ParamDecl>(declRef);
- }
-
- inline Decl* GetInner(DeclRef<GenericDecl> const& declRef)
- {
- // TODO: Should really return a `DeclRef<Decl>` for the inner
- // declaration, and not just a raw pointer
- return declRef.getDecl()->inner.Ptr();
- }
-
-
- //
-
- RefPtr<ArrayExpressionType> getArrayType(
- Type* elementType,
- IntVal* elementCount);
-
- RefPtr<ArrayExpressionType> getArrayType(
- Type* elementType);
-
- RefPtr<NamedExpressionType> getNamedType(
- Session* session,
- DeclRef<TypeDefDecl> const& declRef);
-
- RefPtr<TypeType> getTypeType(
- Type* type);
-
- RefPtr<FuncType> getFuncType(
- Session* session,
- DeclRef<CallableDecl> const& declRef);
-
- RefPtr<GenericDeclRefType> getGenericDeclRefType(
- Session* session,
- DeclRef<GenericDecl> const& declRef);
-
- RefPtr<SamplerStateType> getSamplerStateType(
- Session* session);
-
-
- // Definitions that can't come earlier despite
- // being in templates, because gcc/clang get angry.
- //
- template<typename T>
- void FilteredModifierList<T>::Iterator::operator++()
- {
- current = Adjust(current->next.Ptr());
- }
- //
- template<typename T>
- Modifier* FilteredModifierList<T>::Adjust(Modifier* modifier)
- {
- Modifier* m = modifier;
- for (;;)
- {
- if (!m) return m;
- if (as<T>(m))
- {
- return m;
- }
- m = m->next.Ptr();
- }
- }
-
- // TODO: where should this live?
- SubstitutionSet createDefaultSubstitutions(
- Session* session,
- Decl* decl,
- SubstitutionSet parentSubst);
-
- SubstitutionSet createDefaultSubstitutions(
- Session* session,
- Decl* decl);
-
- DeclRef<Decl> createDefaultSubstitutionsIfNeeded(
- Session* session,
- DeclRef<Decl> declRef);
-
- RefPtr<GenericSubstitution> createDefaultSubsitutionsForGeneric(
- Session* session,
- GenericDecl* genericDecl,
- RefPtr<Substitutions> outerSubst);
-
- RefPtr<GenericSubstitution> findInnerMostGenericSubstitution(Substitutions* subst);
-
- enum class UserDefinedAttributeTargets
- {
- None = 0,
- Struct = 1,
- Var = 2,
- Function = 4,
- All = 7
- };
-
- /// Get the module that a declaration is associated with, if any.
- Module* getModule(Decl* decl);
-
-} // namespace Slang
-
-#endif