From 517513645afb8eaf4841e7b7035f1ba3a9c7cd57 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 15 Jun 2017 13:12:51 -0700 Subject: Rename `Slang::Compiler` -> `Slang` This gets rid of one unecessary namespace. --- source/slang/syntax.h | 4583 ++++++++++++++++++++++++------------------------- 1 file changed, 2290 insertions(+), 2293 deletions(-) (limited to 'source/slang/syntax.h') diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 642f4e99f..8d56cd28e 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -11,2797 +11,2794 @@ namespace Slang { - namespace Compiler - { - using namespace CoreLib::Basic; - class SyntaxVisitor; - class FunctionSyntaxNode; + using namespace CoreLib::Basic; + class SyntaxVisitor; + class FunctionSyntaxNode; - class SyntaxNodeBase : public RefObject - { - public: - CodePosition Position; - }; + class SyntaxNodeBase : public RefObject + { + public: + CodePosition Position; + }; - // - // Other modifiers may have more elaborate data, and so - // are represented as heap-allocated objects, in a linked - // list. - // - class Modifier : public SyntaxNodeBase - { - public: - // Next modifier in linked list of modifiers on same piece of syntax - RefPtr next; + // + // Other modifiers may have more elaborate data, and so + // are represented as heap-allocated objects, in a linked + // list. + // + class Modifier : public SyntaxNodeBase + { + public: + // Next modifier in linked list of modifiers on same piece of syntax + RefPtr next; - // The token that was used to name this modifier. - Token nameToken; - }; + // The token that was used to name this modifier. + Token nameToken; + }; #define SIMPLE_MODIFIER(NAME) \ - class NAME##Modifier : public Modifier {} - - SIMPLE_MODIFIER(Uniform); - SIMPLE_MODIFIER(In); - SIMPLE_MODIFIER(Out); - SIMPLE_MODIFIER(Const); - SIMPLE_MODIFIER(Instance); - SIMPLE_MODIFIER(Builtin); - SIMPLE_MODIFIER(Inline); - SIMPLE_MODIFIER(Public); - SIMPLE_MODIFIER(Require); - SIMPLE_MODIFIER(Param); - SIMPLE_MODIFIER(Extern); - SIMPLE_MODIFIER(Input); - SIMPLE_MODIFIER(Transparent); - SIMPLE_MODIFIER(FromStdLib); - SIMPLE_MODIFIER(Prefix); - SIMPLE_MODIFIER(Postfix); + class NAME##Modifier : public Modifier {} + + SIMPLE_MODIFIER(Uniform); + SIMPLE_MODIFIER(In); + SIMPLE_MODIFIER(Out); + SIMPLE_MODIFIER(Const); + SIMPLE_MODIFIER(Instance); + SIMPLE_MODIFIER(Builtin); + SIMPLE_MODIFIER(Inline); + SIMPLE_MODIFIER(Public); + SIMPLE_MODIFIER(Require); + SIMPLE_MODIFIER(Param); + SIMPLE_MODIFIER(Extern); + SIMPLE_MODIFIER(Input); + SIMPLE_MODIFIER(Transparent); + SIMPLE_MODIFIER(FromStdLib); + SIMPLE_MODIFIER(Prefix); + SIMPLE_MODIFIER(Postfix); #undef SIMPLE_MODIFIER - enum class IntrinsicOp - { - Unknown = 0, + enum class IntrinsicOp + { + Unknown = 0, #define INTRINSIC(NAME) NAME, #include "intrinsic-defs.h" - }; + }; - IntrinsicOp findIntrinsicOp(char const* name); - - // Base class for modifiers that mark something as "intrinsic" - // and thus lacking a direct implementation in the language. - class IntrinsicModifierBase : public Modifier - { - }; + IntrinsicOp findIntrinsicOp(char const* name); - // A modifier that marks something as one of a small set of - // truly intrinsic operations that the compiler knows about - // directly. - class IntrinsicOpModifier : public IntrinsicModifierBase - { - public: - // token that names the intrinsic op - Token opToken; + // Base class for modifiers that mark something as "intrinsic" + // and thus lacking a direct implementation in the language. + class IntrinsicModifierBase : public Modifier + { + }; - // The opcode for the intrinsic operation - IntrinsicOp op = IntrinsicOp::Unknown; - }; + // A modifier that marks something as one of a small set of + // truly intrinsic operations that the compiler knows about + // directly. + class IntrinsicOpModifier : public IntrinsicModifierBase + { + public: + // token that names the intrinsic op + Token opToken; - // A modifier that marks something as an intrinsic function, - // for some subset of targets. - class TargetIntrinsicModifier : public IntrinsicModifierBase - { - public: - // Token that names the target that the operation - // is an intrisic for. - Token targetToken; + // The opcode for the intrinsic operation + IntrinsicOp op = IntrinsicOp::Unknown; + }; - // A custom definition for the operation - Token definitionToken; - }; + // A modifier that marks something as an intrinsic function, + // for some subset of targets. + class TargetIntrinsicModifier : public IntrinsicModifierBase + { + public: + // Token that names the target that the operation + // is an intrisic for. + Token targetToken; + + // A custom definition for the operation + Token definitionToken; + }; + + + + class InOutModifier : public OutModifier {}; + + // This is a special sentinel modifier that gets added + // to the list when we have multiple variable declarations + // all sharing the same modifiers: + // + // static uniform int a : FOO, *b : register(x0); + // + // In this case both `a` and `b` share the syntax + // for part of their modifier list, but then have + // their own modifiers as well: + // + // a: SemanticModifier("FOO") --> SharedModifiers --> StaticModifier --> UniformModifier + // / + // b: RegisterModifier("x0") / + // + class SharedModifiers : public Modifier {}; + + // A GLSL `layout` modifier + // + // We use a distinct modifier for each key that + // appears within the `layout(...)` construct, + // and each key might have an optional value token. + // + // TODO: We probably want a notion of "modifier groups" + // so that we can recover good source location info + // for modifiers that were part of the same vs. + // different constructs. + class GLSLLayoutModifier : public Modifier + { + public: + // THe token used to introduce the modifier is stored + // as the `nameToken` field. + + // TODO: may want to accept a full expression here + Token valToken; + }; + + // We divide GLSL `layout` modifiers into those we have parsed + // (in the sense of having some notion of their semantics), and + // those we have not. + class GLSLParsedLayoutModifier : public GLSLLayoutModifier {}; + class GLSLUnparsedLayoutModifier : public GLSLLayoutModifier {}; + + // Specific cases for known GLSL `layout` modifiers that we need to work with + class GLSLConstantIDLayoutModifier : public GLSLParsedLayoutModifier {}; + class GLSLBindingLayoutModifier : public GLSLParsedLayoutModifier {}; + class GLSLSetLayoutModifier : public GLSLParsedLayoutModifier {}; + class GLSLLocationLayoutModifier : public GLSLParsedLayoutModifier {}; + + // A catch-all for single-keyword modifiers + class SimpleModifier : public Modifier {}; + + // Some GLSL-specific modifiers + class GLSLBufferModifier : public SimpleModifier {}; + class GLSLWriteOnlyModifier : public SimpleModifier {}; + class GLSLReadOnlyModifier : public SimpleModifier {}; + class GLSLPatchModifier : public SimpleModifier {}; + + // Indicates that this is a variable declaration that corresponds to + // a parameter block declaration in the source program. + class ImplicitParameterBlockVariableModifier : public Modifier {}; + + // Indicates that this is a type that corresponds to the element + // type of a parameter block declaration in the source program. + class ImplicitParameterBlockElementTypeModifier : public Modifier {}; + + // An HLSL semantic + class HLSLSemantic : public Modifier + { + public: + Token name; + }; + // An HLSL semantic that affects layout + class HLSLLayoutSemantic : public HLSLSemantic + { + public: + Token registerName; + Token componentMask; + }; - class InOutModifier : public OutModifier {}; + // An HLSL `register` semantic + class HLSLRegisterSemantic : public HLSLLayoutSemantic + { + }; - // This is a special sentinel modifier that gets added - // to the list when we have multiple variable declarations - // all sharing the same modifiers: - // - // static uniform int a : FOO, *b : register(x0); - // - // In this case both `a` and `b` share the syntax - // for part of their modifier list, but then have - // their own modifiers as well: - // - // a: SemanticModifier("FOO") --> SharedModifiers --> StaticModifier --> UniformModifier - // / - // b: RegisterModifier("x0") / - // - class SharedModifiers : public Modifier {}; + // TODO(tfoley): `packoffset` + class HLSLPackOffsetSemantic : public HLSLLayoutSemantic + { + }; - // A GLSL `layout` modifier - // - // We use a distinct modifier for each key that - // appears within the `layout(...)` construct, - // and each key might have an optional value token. - // - // TODO: We probably want a notion of "modifier groups" - // so that we can recover good source location info - // for modifiers that were part of the same vs. - // different constructs. - class GLSLLayoutModifier : public Modifier - { - public: - // THe token used to introduce the modifier is stored - // as the `nameToken` field. + // An HLSL semantic that just associated a declaration with a semantic name + class HLSLSimpleSemantic : public HLSLSemantic + { + }; - // TODO: may want to accept a full expression here - Token valToken; - }; + // GLSL - // We divide GLSL `layout` modifiers into those we have parsed - // (in the sense of having some notion of their semantics), and - // those we have not. - class GLSLParsedLayoutModifier : public GLSLLayoutModifier {}; - class GLSLUnparsedLayoutModifier : public GLSLLayoutModifier {}; + // Directives that came in via the preprocessor, but + // that we need to keep around for later steps + class GLSLPreprocessorDirective : public Modifier + { + }; - // Specific cases for known GLSL `layout` modifiers that we need to work with - class GLSLConstantIDLayoutModifier : public GLSLParsedLayoutModifier {}; - class GLSLBindingLayoutModifier : public GLSLParsedLayoutModifier {}; - class GLSLSetLayoutModifier : public GLSLParsedLayoutModifier {}; - class GLSLLocationLayoutModifier : public GLSLParsedLayoutModifier {}; + // A GLSL `#version` directive + class GLSLVersionDirective : public GLSLPreprocessorDirective + { + public: + // Token giving the version number to use + Token versionNumberToken; - // A catch-all for single-keyword modifiers - class SimpleModifier : public Modifier {}; + // Optional token giving the sub-profile to be used + Token glslProfileToken; + }; - // Some GLSL-specific modifiers - class GLSLBufferModifier : public SimpleModifier {}; - class GLSLWriteOnlyModifier : public SimpleModifier {}; - class GLSLReadOnlyModifier : public SimpleModifier {}; - class GLSLPatchModifier : public SimpleModifier {}; + // A GLSL `#extension` directive + class GLSLExtensionDirective : public GLSLPreprocessorDirective + { + public: + // Token giving the version number to use + Token extensionNameToken; - // Indicates that this is a variable declaration that corresponds to - // a parameter block declaration in the source program. - class ImplicitParameterBlockVariableModifier : public Modifier {}; + // Optional token giving the sub-profile to be used + Token dispositionToken; + }; - // Indicates that this is a type that corresponds to the element - // type of a parameter block declaration in the source program. - class ImplicitParameterBlockElementTypeModifier : public Modifier {}; + class ParameterBlockReflectionName : public Modifier + { + public: + Token nameToken; + }; - // An HLSL semantic - class HLSLSemantic : public Modifier + // Helper class for iterating over a list of heap-allocated modifiers + struct ModifierList + { + struct Iterator { - public: - Token name; - }; + Modifier* current; + Modifier* operator*() + { + return current; + } - // An HLSL semantic that affects layout - class HLSLLayoutSemantic : public HLSLSemantic - { - public: - Token registerName; - Token componentMask; - }; + void operator++() + { + current = current->next.Ptr(); + } - // An HLSL `register` semantic - class HLSLRegisterSemantic : public HLSLLayoutSemantic - { - }; + bool operator!=(Iterator other) + { + return current != other.current; + }; - // TODO(tfoley): `packoffset` - class HLSLPackOffsetSemantic : public HLSLLayoutSemantic - { - }; + Iterator() + : current(nullptr) + {} - // An HLSL semantic that just associated a declaration with a semantic name - class HLSLSimpleSemantic : public HLSLSemantic - { + Iterator(Modifier* modifier) + : current(modifier) + {} }; - // GLSL + ModifierList() + : modifiers(nullptr) + {} - // Directives that came in via the preprocessor, but - // that we need to keep around for later steps - class GLSLPreprocessorDirective : public Modifier - { - }; + ModifierList(Modifier* modifiers) + : modifiers(modifiers) + {} - // A GLSL `#version` directive - class GLSLVersionDirective : public GLSLPreprocessorDirective - { - public: - // Token giving the version number to use - Token versionNumberToken; + Iterator begin() { return Iterator(modifiers); } + Iterator end() { return Iterator(nullptr); } - // Optional token giving the sub-profile to be used - Token glslProfileToken; - }; + Modifier* modifiers; + }; - // A GLSL `#extension` directive - class GLSLExtensionDirective : public GLSLPreprocessorDirective + // Helper class for iterating over heap-allocated modifiers + // of a specific type. + template + struct FilteredModifierList + { + struct Iterator { - public: - // Token giving the version number to use - Token extensionNameToken; + Modifier* current; - // Optional token giving the sub-profile to be used - Token dispositionToken; - }; + T* operator*() + { + return (T*)current; + } - class ParameterBlockReflectionName : public Modifier - { - public: - Token nameToken; - }; + void operator++() + { + current = Adjust(current->next.Ptr()); + } - // Helper class for iterating over a list of heap-allocated modifiers - struct ModifierList - { - struct Iterator + bool operator!=(Iterator other) { - Modifier* current; - - Modifier* operator*() - { - return current; - } - - void operator++() - { - current = current->next.Ptr(); - } - - bool operator!=(Iterator other) - { - return current != other.current; - }; - - Iterator() - : current(nullptr) - {} - - Iterator(Modifier* modifier) - : current(modifier) - {} + return current != other.current; }; - ModifierList() - : modifiers(nullptr) + Iterator() + : current(nullptr) {} - ModifierList(Modifier* modifiers) - : modifiers(modifiers) + Iterator(Modifier* modifier) + : current(modifier) {} - - 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 - struct FilteredModifierList - { - struct Iterator - { - Modifier* current; - - T* operator*() - { - return (T*)current; - } - - void operator++() - { - current = Adjust(current->next.Ptr()); - } - - bool operator!=(Iterator other) - { - return current != other.current; - }; - - Iterator() - : current(nullptr) - {} - - Iterator(Modifier* modifier) - : current(modifier) - {} - }; - - FilteredModifierList() - : modifiers(nullptr) - {} + FilteredModifierList() + : modifiers(nullptr) + {} - FilteredModifierList(Modifier* modifiers) - : modifiers(Adjust(modifiers)) - {} + FilteredModifierList(Modifier* modifiers) + : modifiers(Adjust(modifiers)) + {} - Iterator begin() { return Iterator(modifiers); } - Iterator end() { return Iterator(nullptr); } + Iterator begin() { return Iterator(modifiers); } + Iterator end() { return Iterator(nullptr); } - static Modifier* Adjust(Modifier* modifier) + static Modifier* Adjust(Modifier* modifier) + { + Modifier* m = modifier; + for (;;) { - Modifier* m = modifier; - for (;;) - { - if (!m) return m; - if (dynamic_cast(m)) return m; - m = m->next.Ptr(); - } + if (!m) return m; + if (dynamic_cast(m)) return m; + m = m->next.Ptr(); } + } - 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 first; + Modifier* modifiers; + }; - template - FilteredModifierList getModifiersOfType() { return FilteredModifierList(first.Ptr()); } + // A set of modifiers attached to a syntax node + struct Modifiers + { + // The first modifier in the linked list of heap-allocated modifiers + RefPtr first; - // Find the first modifier of a given type, or return `nullptr` if none is found. - template - T* findModifier() - { - return *getModifiersOfType().begin(); - } + template + FilteredModifierList getModifiersOfType() { return FilteredModifierList(first.Ptr()); } - template - bool hasModifier() { return findModifier() != nullptr; } + // Find the first modifier of a given type, or return `nullptr` if none is found. + template + T* findModifier() + { + return *getModifiersOfType().begin(); + } - FilteredModifierList::Iterator begin() { return FilteredModifierList::Iterator(first.Ptr()); } - FilteredModifierList::Iterator end() { return FilteredModifierList::Iterator(nullptr); } - }; + template + bool hasModifier() { return findModifier() != nullptr; } + FilteredModifierList::Iterator begin() { return FilteredModifierList::Iterator(first.Ptr()); } + FilteredModifierList::Iterator end() { return FilteredModifierList::Iterator(nullptr); } + }; - enum class BaseType - { - // Note(tfoley): These are ordered in terms of promotion rank, so be vareful when messing with this - Void = 0, - Bool, - Int, - UInt, - UInt64, - Float, + enum class BaseType + { + // Note(tfoley): These are ordered in terms of promotion rank, so be vareful when messing with this + + Void = 0, + Bool, + Int, + UInt, + UInt64, + Float, #if 0 - Texture2D = 48, - TextureCube = 49, - Texture2DArray = 50, - Texture2DShadow = 51, - TextureCubeShadow = 52, - Texture2DArrayShadow = 53, - Texture3D = 54, - SamplerState = 4096, SamplerComparisonState = 4097, - Error = 16384, + Texture2D = 48, + TextureCube = 49, + Texture2DArray = 50, + Texture2DShadow = 51, + TextureCubeShadow = 52, + Texture2DArrayShadow = 53, + Texture3D = 54, + SamplerState = 4096, SamplerComparisonState = 4097, + Error = 16384, #endif - }; + }; + + class Decl; + class StructSyntaxNode; + class BasicExpressionType; + class ArrayExpressionType; + class TypeDefDecl; + class DeclRefType; + class NamedExpressionType; + class TypeType; + class GenericDeclRefType; + class VectorExpressionType; + class MatrixExpressionType; + class ArithmeticExpressionType; + class GenericDecl; + class Substitutions; + class TextureType; + class SamplerStateType; + + // A compile-time constant value (usually a type) + class Val : public RefObject + { + public: + // construct a new value by applying a set of parameter + // substitutions to this one + RefPtr Substitute(Substitutions* subst); + + // Lower-level interface for substition. Like the basic + // `Substitute` above, but also takes a by-reference + // integer parameter that should be incremented when + // returning a modified value (this can help the caller + // decide whether they need to do anything). + virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff); + + virtual bool EqualsVal(Val* val) = 0; + virtual String ToString() = 0; + virtual int GetHashCode() = 0; + bool operator == (const Val & v) + { + return EqualsVal(const_cast(&v)); + } + }; - class Decl; - class StructSyntaxNode; - class BasicExpressionType; - class ArrayExpressionType; - class TypeDefDecl; - class DeclRefType; - class NamedExpressionType; - class TypeType; - class GenericDeclRefType; - class VectorExpressionType; - class MatrixExpressionType; - class ArithmeticExpressionType; - class GenericDecl; - class Substitutions; - class TextureType; - class SamplerStateType; - - // A compile-time constant value (usually a type) - class Val : public RefObject - { - public: - // construct a new value by applying a set of parameter - // substitutions to this one - RefPtr Substitute(Substitutions* subst); - - // Lower-level interface for substition. Like the basic - // `Substitute` above, but also takes a by-reference - // integer parameter that should be incremented when - // returning a modified value (this can help the caller - // decide whether they need to do anything). - virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff); - - virtual bool EqualsVal(Val* val) = 0; - virtual String ToString() = 0; - virtual int GetHashCode() = 0; - bool operator == (const Val & v) - { - return EqualsVal(const_cast(&v)); - } - }; + // A compile-time integer (may not have a specific concrete value) + class IntVal : public Val + { + }; - // A compile-time integer (may not have a specific concrete value) - class IntVal : public Val - { - }; + // Try to extract a simple integer value from an `IntVal`. + // This fill assert-fail if the object doesn't represent a literal value. + int GetIntVal(RefPtr val); - // Try to extract a simple integer value from an `IntVal`. - // This fill assert-fail if the object doesn't represent a literal value. - int GetIntVal(RefPtr val); + // Trivial case of a value that is just a constant integer + class ConstantIntVal : public IntVal + { + public: + int value; + + ConstantIntVal(int value) + : value(value) + {} + + virtual bool EqualsVal(Val* val) override; + virtual String ToString() override; + virtual int GetHashCode() override; + }; + + // TODO(tfoley): classes for more general compile-time integers, + // including references to template parameters + + // A type, representing a classifier for some term in the AST. + // + // Types can include "sugar" in that they may refer to a + // `typedef` which gives them a good name when printed as + // part of diagnostic messages. + // + // In order to operation on types, though, we often want + // to look past any sugar, and operate on an underlying + // "canonical" type. The reprsentation caches a pointer to + // a canonical type on every type, so we can easily + // operate on the raw representation when needed. + class ExpressionType : public Val + { + public: + static RefPtr Error; + static RefPtr initializerListType; + static RefPtr Overloaded; - // Trivial case of a value that is just a constant integer - class ConstantIntVal : public IntVal - { - public: - int value; + static Dictionary> sBuiltinTypes; + static Dictionary sMagicDecls; - ConstantIntVal(int value) - : value(value) - {} + // Note: just exists to make sure we can clean up + // canonical types we create along the way + static List> sCanonicalTypes; - virtual bool EqualsVal(Val* val) override; - virtual String ToString() override; - virtual int GetHashCode() override; - }; - // TODO(tfoley): classes for more general compile-time integers, - // including references to template parameters - // A type, representing a classifier for some term in the AST. - // - // Types can include "sugar" in that they may refer to a - // `typedef` which gives them a good name when printed as - // part of diagnostic messages. - // - // In order to operation on types, though, we often want - // to look past any sugar, and operate on an underlying - // "canonical" type. The reprsentation caches a pointer to - // a canonical type on every type, so we can easily - // operate on the raw representation when needed. - class ExpressionType : public Val + static ExpressionType* GetBool(); + static ExpressionType* GetFloat(); + static ExpressionType* GetInt(); + static ExpressionType* GetUInt(); + static ExpressionType* GetVoid(); + static ExpressionType* getInitializerListType(); + static ExpressionType* GetError(); + + public: + virtual String ToString() = 0; + + bool Equals(ExpressionType * type); + bool Equals(RefPtr type); + + bool IsVectorType() { return As() != nullptr; } + bool IsArray() { return As() != nullptr; } + + template + T* As() { - public: - static RefPtr Error; - static RefPtr initializerListType; - static RefPtr Overloaded; + return dynamic_cast(GetCanonicalType()); + } - static Dictionary> sBuiltinTypes; - static Dictionary sMagicDecls; + // Convenience/legacy wrappers for `As<>` + ArithmeticExpressionType * AsArithmeticType() { return As(); } + BasicExpressionType * AsBasicType() { return As(); } + VectorExpressionType * AsVectorType() { return As(); } + MatrixExpressionType * AsMatrixType() { return As(); } + ArrayExpressionType * AsArrayType() { return As(); } - // Note: just exists to make sure we can clean up - // canonical types we create along the way - static List> sCanonicalTypes; + DeclRefType* AsDeclRefType() { return As(); } + NamedExpressionType* AsNamedType(); + bool IsTextureOrSampler(); + bool IsTexture() { return As() != nullptr; } + bool IsSampler() { return As() != nullptr; } + bool IsStruct(); + bool IsClass(); + static void Init(); + static void Finalize(); + ExpressionType* GetCanonicalType(); - static ExpressionType* GetBool(); - static ExpressionType* GetFloat(); - static ExpressionType* GetInt(); - static ExpressionType* GetUInt(); - static ExpressionType* GetVoid(); - static ExpressionType* getInitializerListType(); - static ExpressionType* GetError(); + virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; - public: - virtual String ToString() = 0; + virtual bool EqualsVal(Val* val) override; + protected: + virtual bool EqualsImpl(ExpressionType * type) = 0; + + virtual ExpressionType* CreateCanonicalType() = 0; + ExpressionType* canonicalType = nullptr; + }; + + // A substitution represents a binding of certain + // type-level variables to concrete argument values + class Substitutions : public RefObject + { + public: + // The generic declaration that defines the + // parametesr we are binding to arguments + GenericDecl* genericDecl; + + // The actual values of the arguments + List> args; - bool Equals(ExpressionType * type); - bool Equals(RefPtr type); + // Any further substitutions, relating to outer generic declarations + RefPtr outer; - bool IsVectorType() { return As() != nullptr; } - bool IsArray() { return As() != nullptr; } + // Apply a set of substitutions to the bindings in this substitution + RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff); - template - T* As() + // Check if these are equivalent substitutiosn to another set + bool Equals(Substitutions* subst); + bool operator == (const Substitutions & subst) + { + return Equals(const_cast(&subst)); + } + int GetHashCode() const + { + int rs = 0; + for (auto && v : args) { - return dynamic_cast(GetCanonicalType()); + rs ^= v->GetHashCode(); + rs *= 16777619; } + return rs; + } + }; - // Convenience/legacy wrappers for `As<>` - ArithmeticExpressionType * AsArithmeticType() { return As(); } - BasicExpressionType * AsBasicType() { return As(); } - VectorExpressionType * AsVectorType() { return As(); } - MatrixExpressionType * AsMatrixType() { return As(); } - ArrayExpressionType * AsArrayType() { return As(); } + class SyntaxNode : public SyntaxNodeBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) = 0; + }; - DeclRefType* AsDeclRefType() { return As(); } + class ContainerDecl; + class SpecializeModifier; - NamedExpressionType* AsNamedType(); + // Represents how much checking has been applied to a declaration. + enum class DeclCheckState : uint8_t + { + // The declaration has been parsed, but not checked + Unchecked, - bool IsTextureOrSampler(); - bool IsTexture() { return As() != nullptr; } - bool IsSampler() { return As() != nullptr; } - bool IsStruct(); - bool IsClass(); - static void Init(); - static void Finalize(); - ExpressionType* GetCanonicalType(); + // We are in the process of checking the declaration "header" + // (those parts of the declaration needed in order to + // reference it) + CheckingHeader, - virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; + // We are done checking the declaration header. + CheckedHeader, - virtual bool EqualsVal(Val* val) override; - protected: - virtual bool EqualsImpl(ExpressionType * type) = 0; + // We have checked the declaration fully. + Checked, + }; - virtual ExpressionType* CreateCanonicalType() = 0; - ExpressionType* canonicalType = nullptr; - }; + // A syntax node which can have modifiers appled + class ModifiableSyntaxNode : public SyntaxNode + { + public: + Modifiers modifiers; - // A substitution represents a binding of certain - // type-level variables to concrete argument values - class Substitutions : public RefObject - { - public: - // The generic declaration that defines the - // parametesr we are binding to arguments - GenericDecl* genericDecl; + template + FilteredModifierList GetModifiersOfType() { return FilteredModifierList(modifiers.first.Ptr()); } - // The actual values of the arguments - List> args; + // Find the first modifier of a given type, or return `nullptr` if none is found. + template + T* FindModifier() + { + return *GetModifiersOfType().begin(); + } - // Any further substitutions, relating to outer generic declarations - RefPtr outer; + template + bool HasModifier() { return FindModifier() != nullptr; } + }; - // Apply a set of substitutions to the bindings in this substitution - RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff); + void addModifier( + RefPtr syntax, + RefPtr modifier); - // Check if these are equivalent substitutiosn to another set - bool Equals(Substitutions* subst); - bool operator == (const Substitutions & subst) - { - return Equals(const_cast(&subst)); - } - int GetHashCode() const - { - int rs = 0; - for (auto && v : args) - { - rs ^= v->GetHashCode(); - rs *= 16777619; - } - return rs; - } - }; - class SyntaxNode : public SyntaxNodeBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) = 0; - }; + // An intermediate type to represent either a single declaration, or a group of declarations + class DeclBase : public ModifiableSyntaxNode + { + public: + }; - class ContainerDecl; - class SpecializeModifier; + class Decl : public DeclBase + { + public: + ContainerDecl* ParentDecl; - // Represents how much checking has been applied to a declaration. - enum class DeclCheckState : uint8_t - { - // The declaration has been parsed, but not checked - Unchecked, + Token Name; + String const& getName() { return Name.Content; } + Token const& getNameToken() { return Name; } - // 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, + DeclCheckState checkState = DeclCheckState::Unchecked; - // We have checked the declaration fully. - Checked, - }; + // The next declaration defined in the same container with the same name + Decl* nextInContainerWithSameName = nullptr; - // A syntax node which can have modifiers appled - class ModifiableSyntaxNode : public SyntaxNode + bool IsChecked(DeclCheckState state) { return checkState >= state; } + void SetCheckState(DeclCheckState state) { - public: - Modifiers modifiers; - - template - FilteredModifierList GetModifiersOfType() { return FilteredModifierList(modifiers.first.Ptr()); } + assert(state >= checkState); + checkState = state; + } + }; - // Find the first modifier of a given type, or return `nullptr` if none is found. - template - T* FindModifier() - { - return *GetModifiersOfType().begin(); - } + struct QualType + { + RefPtr type; + bool IsLeftValue; - template - bool HasModifier() { return FindModifier() != nullptr; } - }; + QualType() + : IsLeftValue(false) + {} - void addModifier( - RefPtr syntax, - RefPtr modifier); + QualType(RefPtr type) + : type(type) + , IsLeftValue(false) + {} + QualType(ExpressionType* type) + : type(type) + , IsLeftValue(false) + {} - // An intermediate type to represent either a single declaration, or a group of declarations - class DeclBase : public ModifiableSyntaxNode + void operator=(RefPtr t) { - public: - }; + *this = QualType(t); + } - class Decl : public DeclBase + void operator=(ExpressionType* t) { - public: - ContainerDecl* ParentDecl; + *this = QualType(t); + } - Token Name; - String const& getName() { return Name.Content; } - Token const& getNameToken() { return Name; } + ExpressionType* Ptr() { return type.Ptr(); } + operator RefPtr() { return type; } + RefPtr operator->() { return type; } + }; - DeclCheckState checkState = DeclCheckState::Unchecked; + class ExpressionSyntaxNode : public SyntaxNode + { + public: + QualType Type; + ExpressionSyntaxNode() + {} + }; - // The next declaration defined in the same container with the same name - Decl* nextInContainerWithSameName = nullptr; - bool IsChecked(DeclCheckState state) { return checkState >= state; } - void SetCheckState(DeclCheckState state) - { - assert(state >= checkState); - checkState = state; - } - }; - struct QualType - { - RefPtr type; - bool IsLeftValue; - QualType() - : IsLeftValue(false) - {} + // A reference to a declaration, which may include + // substitutions for generic parameters. + struct DeclRef + { + typedef Decl DeclType; - QualType(RefPtr type) - : type(type) - , IsLeftValue(false) - {} + // The underlying declaration + Decl* decl = nullptr; + Decl* GetDecl() const { return decl; } - QualType(ExpressionType* type) - : type(type) - , IsLeftValue(false) - {} + // Optionally, a chain of substititions to perform + RefPtr substitutions; - void operator=(RefPtr t) - { - *this = QualType(t); - } + DeclRef() + {} - void operator=(ExpressionType* t) - { - *this = QualType(t); - } + DeclRef(Decl* decl, RefPtr substitutions) + : decl(decl) + , substitutions(substitutions) + {} - ExpressionType* Ptr() { return type.Ptr(); } + // Apply substitutions to a type or ddeclaration + RefPtr Substitute(RefPtr type) const; + DeclRef Substitute(DeclRef declRef) const; - operator RefPtr() { return type; } - RefPtr operator->() { return type; } - }; + // Apply substitutions to an expression + RefPtr Substitute(RefPtr expr) const; - class ExpressionSyntaxNode : public SyntaxNode - { - public: - QualType Type; - ExpressionSyntaxNode() - {} - }; + // Apply substitutions to this declaration reference + DeclRef SubstituteImpl(Substitutions* subst, int* ioDiff); + // Check if this is an equivalent declaration reference to another + bool Equals(DeclRef const& declRef) const; + bool operator == (const DeclRef& other) const + { + return Equals(other); + } + // Convenience accessors for common properties of declarations + String const& GetName() const; + DeclRef GetParent() const; + // "dynamic cast" to a more specific declaration reference type + template + T As() const + { + T result; + result.decl = dynamic_cast(decl); + result.substitutions = substitutions; + return result; + } - // A reference to a declaration, which may include - // substitutions for generic parameters. - struct DeclRef + // Implicit conversion mostly so we can use a `DeclRef` + // in a conditional context + operator Decl*() const { - typedef Decl DeclType; + return decl; + } - // The underlying declaration - Decl* decl = nullptr; - Decl* GetDecl() const { return decl; } + int GetHashCode() const; + }; - // Optionally, a chain of substititions to perform - RefPtr substitutions; + // Helper macro for defining `DeclRef` subtypes + #define SLANG_DECLARE_DECL_REF(D) \ + typedef D DeclType; \ + D* GetDecl() const { return (D*) decl; } \ + /* */ - DeclRef() - {} - DeclRef(Decl* decl, RefPtr substitutions) - : decl(decl) - , substitutions(substitutions) - {} - // Apply substitutions to a type or ddeclaration - RefPtr Substitute(RefPtr type) const; - DeclRef Substitute(DeclRef declRef) const; + // The type of a reference to an overloaded name + class OverloadGroupType : public ExpressionType + { + public: + virtual String ToString() override; + + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; + + // The type of an initializer-list expression (before it has + // been coerced to some other type) + class InitializerListType : public ExpressionType + { + public: + virtual String ToString() override; - // Apply substitutions to an expression - RefPtr Substitute(RefPtr expr) const; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - // Apply substitutions to this declaration reference - DeclRef SubstituteImpl(Substitutions* subst, int* ioDiff); + // The type of an expression that was erroneous + class ErrorType : public ExpressionType + { + public: + virtual String ToString() override; - // Check if this is an equivalent declaration reference to another - bool Equals(DeclRef const& declRef) const; - bool operator == (const DeclRef& other) const - { - return Equals(other); - } + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - // Convenience accessors for common properties of declarations - String const& GetName() const; - DeclRef GetParent() const; + // A type that takes the form of a reference to some declaration + class DeclRefType : public ExpressionType + { + public: + DeclRef declRef; + + virtual String ToString() override; + virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; + + static DeclRefType* Create(DeclRef declRef); + + protected: + DeclRefType() + {} + DeclRefType(DeclRef declRef) + : declRef(declRef) + {} + virtual int GetHashCode() override; + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + }; + + // Base class for types that can be used in arithmetic expressions + class ArithmeticExpressionType : public DeclRefType + { + public: + virtual BasicExpressionType* GetScalarType() = 0; + }; - // "dynamic cast" to a more specific declaration reference type - template - T As() const - { - T result; - result.decl = dynamic_cast(decl); - result.substitutions = substitutions; - return result; - } + class FunctionDeclBase; - // Implicit conversion mostly so we can use a `DeclRef` - // in a conditional context - operator Decl*() const - { - return decl; - } + class BasicExpressionType : public ArithmeticExpressionType + { + public: + BaseType BaseType; - int GetHashCode() const; - }; + BasicExpressionType() + { + BaseType = Slang::BaseType::Int; + } + BasicExpressionType(Slang::BaseType baseType) + { + BaseType = baseType; + } + virtual CoreLib::Basic::String ToString() override; + protected: + virtual BasicExpressionType* GetScalarType() override; + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + }; - // Helper macro for defining `DeclRef` subtypes - #define SLANG_DECLARE_DECL_REF(D) \ - typedef D DeclType; \ - D* GetDecl() const { return (D*) decl; } \ - /* */ + class TextureTypeBase : public DeclRefType + { + public: + // The type that results from fetching an element from this texture + RefPtr elementType; + // Bits representing the kind of texture type we are looking at + // (e.g., `Texture2DMS` vs. `TextureCubeArray`) + typedef uint16_t Flavor; + Flavor flavor; - // The type of a reference to an overloaded name - class OverloadGroupType : public ExpressionType + enum { - public: - virtual String ToString() override; + // Mask for the overall "shape" of the texture + ShapeMask = SLANG_RESOURCE_BASE_SHAPE_MASK, - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + // Flag for whether the shape has "array-ness" + ArrayFlag = SLANG_TEXTURE_ARRAY_FLAG, - // The type of an initializer-list expression (before it has - // been coerced to some other type) - class InitializerListType : public ExpressionType - { - public: - virtual String ToString() override; + // Whether or not the texture stores multiple samples per pixel + MultisampleFlag = SLANG_TEXTURE_MULTISAMPLE_FLAG, - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; + // Whether or not this is a shadow texture + // + // TODO(tfoley): is this even meaningful/used? + // ShadowFlag = 0x80, }; - // The type of an expression that was erroneous - class ErrorType : public ExpressionType + enum Shape : uint8_t { - public: - virtual String ToString() override; + Shape1D = SLANG_TEXTURE_1D, + Shape2D = SLANG_TEXTURE_2D, + Shape3D = SLANG_TEXTURE_3D, + ShapeCube = SLANG_TEXTURE_CUBE, - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; + Shape1DArray = Shape1D | ArrayFlag, + Shape2DArray = Shape2D | ArrayFlag, + // No Shape3DArray + ShapeCubeArray = ShapeCube | ArrayFlag, }; + - // A type that takes the form of a reference to some declaration - class DeclRefType : public ExpressionType - { - public: - DeclRef declRef; - - virtual String ToString() override; - virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; + Shape GetBaseShape() const { return Shape(flavor & ShapeMask); } + bool isArray() const { return (flavor & ArrayFlag) != 0; } + bool isMultisample() const { return (flavor & MultisampleFlag) != 0; } +// bool isShadow() const { return (flavor & ShadowFlag) != 0; } - static DeclRefType* Create(DeclRef declRef); + SlangResourceShape getShape() const { return flavor & 0xFF; } + SlangResourceAccess getAccess() const { return (flavor >> 8) & 0xFF; } - protected: - DeclRefType() - {} - DeclRefType(DeclRef declRef) - : declRef(declRef) - {} - virtual int GetHashCode() override; - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - }; + TextureTypeBase( + Flavor flavor, + RefPtr elementType) + : elementType(elementType) + , flavor(flavor) + {} + }; - // Base class for types that can be used in arithmetic expressions - class ArithmeticExpressionType : public DeclRefType + class TextureType : public TextureTypeBase + { + public: + TextureType( + Flavor flavor, + RefPtr elementType) + : TextureTypeBase(flavor, elementType) + {} + }; + + // This is a base type for texture/sampler pairs, + // as they exist in, e.g., GLSL + class TextureSamplerType : public TextureTypeBase + { + public: + TextureSamplerType( + Flavor flavor, + RefPtr elementType) + : TextureTypeBase(flavor, elementType) + {} + }; + + // This is a base type for `image*` types, as they exist in GLSL + class GLSLImageType : public TextureTypeBase + { + public: + GLSLImageType( + Flavor flavor, + RefPtr elementType) + : TextureTypeBase(flavor, elementType) + {} + }; + + class SamplerStateType : public DeclRefType + { + public: + // What flavor of sampler state is this + enum class Flavor : uint8_t { - public: - virtual BasicExpressionType* GetScalarType() = 0; + SamplerState, + SamplerComparisonState, }; + Flavor flavor; + }; - class FunctionDeclBase; + // Other cases of generic types known to the compiler + class BuiltinGenericType : public DeclRefType + { + public: + RefPtr elementType; + }; - class BasicExpressionType : public ArithmeticExpressionType - { - public: - BaseType BaseType; + // Types that behave like pointers, in that they can be + // dereferenced (implicitly) to access members defined + // in the element type. + class PointerLikeType : public BuiltinGenericType + {}; - BasicExpressionType() - { - BaseType = Compiler::BaseType::Int; - } - BasicExpressionType(Compiler::BaseType baseType) - { - BaseType = baseType; - } - virtual CoreLib::Basic::String ToString() override; - protected: - virtual BasicExpressionType* GetScalarType() override; - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - }; + // Generic types used in existing Slang code + // TODO(tfoley): check that these are actually working right... + class PatchType : public PointerLikeType {}; + class StorageBufferType : public BuiltinGenericType {}; + class UniformBufferType : public PointerLikeType {}; + class PackedBufferType : public BuiltinGenericType {}; + // HLSL buffer-type resources - class TextureTypeBase : public DeclRefType - { - public: - // The type that results from fetching an element from this texture - RefPtr elementType; + class HLSLBufferType : public BuiltinGenericType {}; + class HLSLRWBufferType : public BuiltinGenericType {}; + class HLSLStructuredBufferType : public BuiltinGenericType {}; + class HLSLRWStructuredBufferType : public BuiltinGenericType {}; - // Bits representing the kind of texture type we are looking at - // (e.g., `Texture2DMS` vs. `TextureCubeArray`) - typedef uint16_t Flavor; - Flavor flavor; + class UntypedBufferResourceType : public DeclRefType {}; + class HLSLByteAddressBufferType : public UntypedBufferResourceType {}; + class HLSLRWByteAddressBufferType : public UntypedBufferResourceType {}; - enum - { - // Mask for the overall "shape" of the texture - ShapeMask = SLANG_RESOURCE_BASE_SHAPE_MASK, + class HLSLAppendStructuredBufferType : public BuiltinGenericType {}; + class HLSLConsumeStructuredBufferType : public BuiltinGenericType {}; - // Flag for whether the shape has "array-ness" - ArrayFlag = SLANG_TEXTURE_ARRAY_FLAG, + class HLSLInputPatchType : public BuiltinGenericType {}; + class HLSLOutputPatchType : public BuiltinGenericType {}; - // Whether or not the texture stores multiple samples per pixel - MultisampleFlag = SLANG_TEXTURE_MULTISAMPLE_FLAG, + // HLSL geometry shader output stream types - // Whether or not this is a shadow texture - // - // TODO(tfoley): is this even meaningful/used? - // ShadowFlag = 0x80, - }; + class HLSLStreamOutputType : public BuiltinGenericType {}; + class HLSLPointStreamType : public HLSLStreamOutputType {}; + class HLSLLineStreamType : public HLSLStreamOutputType {}; + class HLSLTriangleStreamType : public HLSLStreamOutputType {}; - enum Shape : uint8_t - { - Shape1D = SLANG_TEXTURE_1D, - Shape2D = SLANG_TEXTURE_2D, - Shape3D = SLANG_TEXTURE_3D, - ShapeCube = SLANG_TEXTURE_CUBE, - - Shape1DArray = Shape1D | ArrayFlag, - Shape2DArray = Shape2D | ArrayFlag, - // No Shape3DArray - ShapeCubeArray = ShapeCube | ArrayFlag, - }; - + // + class GLSLInputAttachmentType : public DeclRefType {}; - Shape GetBaseShape() const { return Shape(flavor & ShapeMask); } - bool isArray() const { return (flavor & ArrayFlag) != 0; } - bool isMultisample() const { return (flavor & MultisampleFlag) != 0; } -// bool isShadow() const { return (flavor & ShadowFlag) != 0; } + // Base class for types used when desugaring parameter block + // declarations, includeing HLSL `cbuffer` or GLSL `uniform` blocks. + class ParameterBlockType : public PointerLikeType {}; - SlangResourceShape getShape() const { return flavor & 0xFF; } - SlangResourceAccess getAccess() const { return (flavor >> 8) & 0xFF; } + class UniformParameterBlockType : public ParameterBlockType {}; + class VaryingParameterBlockType : public ParameterBlockType {}; - TextureTypeBase( - Flavor flavor, - RefPtr elementType) - : elementType(elementType) - , flavor(flavor) - {} - }; - - class TextureType : public TextureTypeBase - { - public: - TextureType( - Flavor flavor, - RefPtr elementType) - : TextureTypeBase(flavor, elementType) - {} - }; - - // This is a base type for texture/sampler pairs, - // as they exist in, e.g., GLSL - class TextureSamplerType : public TextureTypeBase - { - public: - TextureSamplerType( - Flavor flavor, - RefPtr elementType) - : TextureTypeBase(flavor, elementType) - {} - }; - - // This is a base type for `image*` types, as they exist in GLSL - class GLSLImageType : public TextureTypeBase - { - public: - GLSLImageType( - Flavor flavor, - RefPtr elementType) - : TextureTypeBase(flavor, elementType) - {} - }; + // Type for HLSL `cbuffer` declarations, and `ConstantBuffer` + // ALso used for GLSL `uniform` blocks. + class ConstantBufferType : public UniformParameterBlockType {}; - class SamplerStateType : public DeclRefType - { - public: - // What flavor of sampler state is this - enum class Flavor : uint8_t - { - SamplerState, - SamplerComparisonState, - }; - Flavor flavor; - }; + // Type for HLSL `tbuffer` declarations, and `TextureBuffer` + class TextureBufferType : public UniformParameterBlockType {}; - // Other cases of generic types known to the compiler - class BuiltinGenericType : public DeclRefType - { - public: - RefPtr elementType; - }; + // Type for GLSL `in` and `out` blocks + class GLSLInputParameterBlockType : public VaryingParameterBlockType {}; + class GLSLOutputParameterBlockType : public VaryingParameterBlockType {}; - // Types that behave like pointers, in that they can be - // dereferenced (implicitly) to access members defined - // in the element type. - class PointerLikeType : public BuiltinGenericType - {}; + // Type for GLLSL `buffer` blocks + class GLSLShaderStorageBufferType : public UniformParameterBlockType {}; - // Generic types used in existing Slang code - // TODO(tfoley): check that these are actually working right... - class PatchType : public PointerLikeType {}; - class StorageBufferType : public BuiltinGenericType {}; - class UniformBufferType : public PointerLikeType {}; - class PackedBufferType : public BuiltinGenericType {}; + class ArrayExpressionType : public ExpressionType + { + public: + RefPtr BaseType; + RefPtr ArrayLength; + virtual CoreLib::Basic::String ToString() override; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; + + // The "type" of an expression that resolves to a type. + // For example, in the expression `float(2)` the sub-expression, + // `float` would have the type `TypeType(float)`. + class TypeType : public ExpressionType + { + public: + TypeType(RefPtr type) + : type(type) + {} - // HLSL buffer-type resources + // The type that this is the type of... + RefPtr type; - class HLSLBufferType : public BuiltinGenericType {}; - class HLSLRWBufferType : public BuiltinGenericType {}; - class HLSLStructuredBufferType : public BuiltinGenericType {}; - class HLSLRWStructuredBufferType : public BuiltinGenericType {}; - class UntypedBufferResourceType : public DeclRefType {}; - class HLSLByteAddressBufferType : public UntypedBufferResourceType {}; - class HLSLRWByteAddressBufferType : public UntypedBufferResourceType {}; + virtual String ToString() override; - class HLSLAppendStructuredBufferType : public BuiltinGenericType {}; - class HLSLConsumeStructuredBufferType : public BuiltinGenericType {}; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - class HLSLInputPatchType : public BuiltinGenericType {}; - class HLSLOutputPatchType : public BuiltinGenericType {}; + class GenericDecl; - // HLSL geometry shader output stream types + // A vector type, e.g., `vector` + class VectorExpressionType : public ArithmeticExpressionType + { + public: +#if 0 + VectorExpressionType( + RefPtr elementType, + RefPtr elementCount) + : elementType(elementType) + , elementCount(elementCount) + {} +#endif - class HLSLStreamOutputType : public BuiltinGenericType {}; - class HLSLPointStreamType : public HLSLStreamOutputType {}; - class HLSLLineStreamType : public HLSLStreamOutputType {}; - class HLSLTriangleStreamType : public HLSLStreamOutputType {}; + // The type of vector elements. + // As an invariant, this should be a basic type or an alias. + RefPtr elementType; - // - class GLSLInputAttachmentType : public DeclRefType {}; + // The number of elements + RefPtr elementCount; - // Base class for types used when desugaring parameter block - // declarations, includeing HLSL `cbuffer` or GLSL `uniform` blocks. - class ParameterBlockType : public PointerLikeType {}; + virtual String ToString() override; - class UniformParameterBlockType : public ParameterBlockType {}; - class VaryingParameterBlockType : public ParameterBlockType {}; + protected: + virtual BasicExpressionType* GetScalarType() override; + }; - // Type for HLSL `cbuffer` declarations, and `ConstantBuffer` - // ALso used for GLSL `uniform` blocks. - class ConstantBufferType : public UniformParameterBlockType {}; + // A matrix type, e.g., `matrix` + class MatrixExpressionType : public ArithmeticExpressionType + { + public: + // TODO: consider adding these back for convenience, + // with a way to initialize them on-demand from the + // real storage (which is in the `DeclRefType` +#if 0 + // The type of vector elements. + // As an invariant, this should be a basic type or an alias. + RefPtr elementType; - // Type for HLSL `tbuffer` declarations, and `TextureBuffer` - class TextureBufferType : public UniformParameterBlockType {}; + // The type of the matrix rows + RefPtr rowType; - // Type for GLSL `in` and `out` blocks - class GLSLInputParameterBlockType : public VaryingParameterBlockType {}; - class GLSLOutputParameterBlockType : public VaryingParameterBlockType {}; + // The number of rows and columns + RefPtr rowCount; + RefPtr colCount; +#endif + ExpressionType* getElementType(); + IntVal* getRowCount(); + IntVal* getColumnCount(); - // Type for GLLSL `buffer` blocks - class GLSLShaderStorageBufferType : public UniformParameterBlockType {}; - class ArrayExpressionType : public ExpressionType - { - public: - RefPtr BaseType; - RefPtr ArrayLength; - virtual CoreLib::Basic::String ToString() override; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + virtual String ToString() override; - // The "type" of an expression that resolves to a type. - // For example, in the expression `float(2)` the sub-expression, - // `float` would have the type `TypeType(float)`. - class TypeType : public ExpressionType - { - public: - TypeType(RefPtr type) - : type(type) - {} + protected: + virtual BasicExpressionType* GetScalarType() override; + }; - // The type that this is the type of... - RefPtr type; + inline BaseType GetVectorBaseType(VectorExpressionType* vecType) { + return vecType->elementType->AsBasicType()->BaseType; + } + inline int GetVectorSize(VectorExpressionType* vecType) + { + auto constantVal = vecType->elementCount.As(); + if (constantVal) + return constantVal->value; + // TODO: what to do in this case? + return 0; + } - virtual String ToString() override; + class Type + { + public: + RefPtr DataType; + // ContrainedWorlds: Implementation must be defined at at least one of of these worlds in order to satisfy global dependency + // FeasibleWorlds: The component can be computed at any of these worlds + EnumerableHashSet ConstrainedWorlds, FeasibleWorlds; + EnumerableHashSet PinnedWorlds; + }; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + class ContainerDecl; - class GenericDecl; - // A vector type, e.g., `vector` - class VectorExpressionType : public ArithmeticExpressionType - { - public: -#if 0 - VectorExpressionType( - RefPtr elementType, - RefPtr elementCount) - : elementType(elementType) - , elementCount(elementCount) - {} -#endif + // A group of declarations that should be treated as a unit + class DeclGroup : public DeclBase + { + public: + List> decls; - // The type of vector elements. - // As an invariant, this should be a basic type or an alias. - RefPtr elementType; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // The number of elements - RefPtr elementCount; + template + struct FilteredMemberList + { + typedef RefPtr Element; - virtual String ToString() override; + FilteredMemberList() + : mBegin(NULL) + , mEnd(NULL) + {} - protected: - virtual BasicExpressionType* GetScalarType() override; - }; + explicit FilteredMemberList( + List const& list) + : mBegin(Adjust(list.begin(), list.end())) + , mEnd(list.end()) + {} - // A matrix type, e.g., `matrix` - class MatrixExpressionType : public ArithmeticExpressionType + struct Iterator { - public: - // TODO: consider adding these back for convenience, - // with a way to initialize them on-demand from the - // real storage (which is in the `DeclRefType` -#if 0 - // The type of vector elements. - // As an invariant, this should be a basic type or an alias. - RefPtr elementType; - - // The type of the matrix rows - RefPtr rowType; - - // The number of rows and columns - RefPtr rowCount; - RefPtr colCount; -#endif - ExpressionType* getElementType(); - IntVal* getRowCount(); - IntVal* getColumnCount(); + Element* mCursor; + Element* mEnd; + bool operator!=(Iterator const& other) + { + return mCursor != other.mCursor; + } - virtual String ToString() override; + void operator++() + { + mCursor = Adjust(mCursor + 1, mEnd); + } - protected: - virtual BasicExpressionType* GetScalarType() override; + RefPtr& operator*() + { + return *(RefPtr*)mCursor; + } }; - inline BaseType GetVectorBaseType(VectorExpressionType* vecType) { - return vecType->elementType->AsBasicType()->BaseType; - } - - inline int GetVectorSize(VectorExpressionType* vecType) + Iterator begin() { - auto constantVal = vecType->elementCount.As(); - if (constantVal) - return constantVal->value; - // TODO: what to do in this case? - return 0; + Iterator iter = { mBegin, mEnd }; + return iter; } - class Type - { - public: - RefPtr DataType; - // ContrainedWorlds: Implementation must be defined at at least one of of these worlds in order to satisfy global dependency - // FeasibleWorlds: The component can be computed at any of these worlds - EnumerableHashSet ConstrainedWorlds, FeasibleWorlds; - EnumerableHashSet PinnedWorlds; - }; - - class ContainerDecl; - - - // A group of declarations that should be treated as a unit - class DeclGroup : public DeclBase + Iterator end() { - public: - List> decls; - - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + Iterator iter = { mEnd, mEnd }; + return iter; + } - template - struct FilteredMemberList + static Element* Adjust(Element* cursor, Element* end) { - typedef RefPtr Element; - - FilteredMemberList() - : mBegin(NULL) - , mEnd(NULL) - {} - - explicit FilteredMemberList( - List const& list) - : mBegin(Adjust(list.begin(), list.end())) - , mEnd(list.end()) - {} - - struct Iterator - { - Element* mCursor; - Element* mEnd; - - bool operator!=(Iterator const& other) - { - return mCursor != other.mCursor; - } - - void operator++() - { - mCursor = Adjust(mCursor + 1, mEnd); - } - - RefPtr& operator*() - { - return *(RefPtr*)mCursor; - } - }; - - Iterator begin() + while (cursor != end) { - Iterator iter = { mBegin, mEnd }; - return iter; + if ((*cursor).As()) + return cursor; + cursor++; } + return cursor; + } - Iterator end() + // TODO(tfoley): It is ugly to have these. + // We should probably fix the call sites instead. + RefPtr& First() { return *begin(); } + int Count() + { + int count = 0; + for (auto iter : (*this)) { - Iterator iter = { mEnd, mEnd }; - return iter; + (void)iter; + count++; } + return count; + } - static Element* Adjust(Element* cursor, Element* end) + List> ToArray() + { + List> result; + for (auto element : (*this)) { - while (cursor != end) - { - if ((*cursor).As()) - return cursor; - cursor++; - } - return cursor; + result.Add(element); } + return result; + } - // TODO(tfoley): It is ugly to have these. - // We should probably fix the call sites instead. - RefPtr& First() { return *begin(); } - int Count() - { - int count = 0; - for (auto iter : (*this)) - { - (void)iter; - count++; - } - return count; - } + Element* mBegin; + Element* mEnd; + }; - List> ToArray() - { - List> result; - for (auto element : (*this)) - { - result.Add(element); - } - return result; - } + struct TransparentMemberInfo + { + // The declaration of the transparent member + Decl* decl; + }; - Element* mBegin; - Element* mEnd; - }; + // A "container" decl is a parent to other declarations + class ContainerDecl : public Decl + { + public: + List> Members; - struct TransparentMemberInfo + template + FilteredMemberList GetMembersOfType() { - // The declaration of the transparent member - Decl* decl; - }; + return FilteredMemberList(Members); + } - // A "container" decl is a parent to other declarations - class ContainerDecl : public Decl - { - public: - List> Members; - template - FilteredMemberList GetMembersOfType() - { - return FilteredMemberList(Members); - } + // Dictionary for looking up members by name. + // This is built on demand before performing lookup. + Dictionary memberDictionary; + // Whether the `memberDictionary` is valid. + // Should be set to `false` if any members get added/remoed. + bool memberDictionaryIsValid = false; - // Dictionary for looking up members by name. - // This is built on demand before performing lookup. - Dictionary memberDictionary; + // A list of transparent members, to be used in lookup + // Note: this is only valid if `memberDictionaryIsValid` is true + List transparentMembers; + }; - // Whether the `memberDictionary` is valid. - // Should be set to `false` if any members get added/remoed. - bool memberDictionaryIsValid = false; + template + struct FilteredMemberRefList + { + List> const& decls; + RefPtr substitutions; + + FilteredMemberRefList( + List> const& decls, + RefPtr substitutions) + : decls(decls) + , substitutions(substitutions) + {} + + int Count() const + { + int count = 0; + for (auto d : *this) + count++; + return count; + } - // A list of transparent members, to be used in lookup - // Note: this is only valid if `memberDictionaryIsValid` is true - List transparentMembers; - }; + List ToArray() const + { + List result; + for (auto d : *this) + result.Add(d); + return result; + } - template - struct FilteredMemberRefList + struct Iterator { - List> const& decls; - RefPtr substitutions; + FilteredMemberRefList const* list; + RefPtr* ptr; + RefPtr* end; - FilteredMemberRefList( - List> const& decls, - RefPtr substitutions) - : decls(decls) - , substitutions(substitutions) + Iterator() : list(nullptr), ptr(nullptr) {} + Iterator( + FilteredMemberRefList const* list, + RefPtr* ptr, + RefPtr* end) + : list(list) + , ptr(ptr) + , end(end) {} - int Count() const + bool operator!=(Iterator other) { - int count = 0; - for (auto d : *this) - count++; - return count; + return ptr != other.ptr; } - List ToArray() const + void operator++() { - List result; - for (auto d : *this) - result.Add(d); - return result; + ptr = list->Adjust(ptr + 1, end); } - struct Iterator - { - FilteredMemberRefList const* list; - RefPtr* ptr; - RefPtr* end; - - Iterator() : list(nullptr), ptr(nullptr) {} - Iterator( - FilteredMemberRefList const* list, - RefPtr* ptr, - RefPtr* end) - : list(list) - , ptr(ptr) - , end(end) - {} - - bool operator!=(Iterator other) - { - return ptr != other.ptr; - } - - void operator++() - { - ptr = list->Adjust(ptr + 1, end); - } - - T operator*() - { - return DeclRef(ptr->Ptr(), list->substitutions).As(); - } - }; - - Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); } - Iterator end() const { return Iterator(this, decls.end(), decls.end()); } - - RefPtr* Adjust(RefPtr* ptr, RefPtr* end) const + T operator*() { - while (ptr != end) - { - DeclRef declRef(ptr->Ptr(), substitutions); - if (declRef.As()) - return ptr; - ptr++; - } - return end; + return DeclRef(ptr->Ptr(), list->substitutions).As(); } }; - struct ContainerDeclRef : DeclRef - { - SLANG_DECLARE_DECL_REF(ContainerDecl); - - FilteredMemberRefList GetMembers() const - { - return FilteredMemberRefList(GetDecl()->Members, substitutions); - } + Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); } + Iterator end() const { return Iterator(this, decls.end(), decls.end()); } - template - FilteredMemberRefList GetMembersOfType() const + RefPtr* Adjust(RefPtr* ptr, RefPtr* end) const + { + while (ptr != end) { - return FilteredMemberRefList(GetDecl()->Members, substitutions); + DeclRef declRef(ptr->Ptr(), substitutions); + if (declRef.As()) + return ptr; + ptr++; } + return end; + } + }; - }; + struct ContainerDeclRef : DeclRef + { + SLANG_DECLARE_DECL_REF(ContainerDecl); - // - // Type Expressions - // + FilteredMemberRefList GetMembers() const + { + return FilteredMemberRefList(GetDecl()->Members, substitutions); + } - // 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 + template + FilteredMemberRefList GetMembersOfType() const { - TypeExp() {} - TypeExp(TypeExp const& other) - : exp(other.exp) - , type(other.type) - {} - explicit TypeExp(RefPtr exp) - : exp(exp) - {} - TypeExp(RefPtr exp, RefPtr type) - : exp(exp) - , type(type) - {} + return FilteredMemberRefList(GetDecl()->Members, substitutions); + } - RefPtr exp; - RefPtr type; + }; - bool Equals(ExpressionType* other) { - return type->Equals(other); - } - bool Equals(RefPtr other) { - return type->Equals(other.Ptr()); - } - ExpressionType* Ptr() { return type.Ptr(); } - operator RefPtr() - { - return type; - } - ExpressionType* operator->() { return Ptr(); } + // + // Type Expressions + // - TypeExp Accept(SyntaxVisitor* visitor); - }; + // 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 exp) + : exp(exp) + {} + TypeExp(RefPtr exp, RefPtr type) + : exp(exp) + , type(type) + {} + + RefPtr exp; + RefPtr type; + + bool Equals(ExpressionType* other) { + return type->Equals(other); + } + bool Equals(RefPtr other) { + return type->Equals(other.Ptr()); + } + ExpressionType* Ptr() { return type.Ptr(); } + operator RefPtr() + { + return type; + } + ExpressionType* operator->() { return Ptr(); } + TypeExp Accept(SyntaxVisitor* visitor); + }; - // - // Declarations - // - // Base class for all variable-like declarations - class VarDeclBase : public Decl - { - public: - // Type of the variable - TypeExp Type; + // + // Declarations + // - ExpressionType* getType() { return Type.type.Ptr(); } + // Base class for all variable-like declarations + class VarDeclBase : public Decl + { + public: + // Type of the variable + TypeExp Type; - // Initializer expression (optional) - RefPtr Expr; - }; + ExpressionType* getType() { return Type.type.Ptr(); } - struct VarDeclBaseRef : DeclRef - { - SLANG_DECLARE_DECL_REF(VarDeclBase); + // Initializer expression (optional) + RefPtr Expr; + }; - RefPtr GetType() const { return Substitute(GetDecl()->Type); } + struct VarDeclBaseRef : DeclRef + { + SLANG_DECLARE_DECL_REF(VarDeclBase); - RefPtr getInitExpr() const { return Substitute(GetDecl()->Expr); } - }; + RefPtr GetType() const { return Substitute(GetDecl()->Type); } - // A field of a `struct` type - class StructField : public VarDeclBase - { - public: - StructField() - {} - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + RefPtr getInitExpr() const { return Substitute(GetDecl()->Expr); } + }; - struct FieldDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(StructField) - }; + // A field of a `struct` type + class StructField : public VarDeclBase + { + public: + StructField() + {} + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // An `AggTypeDeclBase` captures the shared functionality - // between true aggregate type declarations and extension - // declarations: - // - // - Both can container members (they are `ContainerDecl`s) - // - Both can have declared bases - // - Both expose a `this` variable in their body - // - class AggTypeDeclBase : public ContainerDecl - { - public: - }; + struct FieldDeclRef : VarDeclBaseRef + { + SLANG_DECLARE_DECL_REF(StructField) + }; + + // An `AggTypeDeclBase` captures the shared functionality + // between true aggregate type declarations and extension + // declarations: + // + // - Both can container members (they are `ContainerDecl`s) + // - Both can have declared bases + // - Both expose a `this` variable in their body + // + class AggTypeDeclBase : public ContainerDecl + { + public: + }; - struct AggTypeDeclBaseRef : ContainerDeclRef - { - SLANG_DECLARE_DECL_REF(AggTypeDeclBase); - }; + struct AggTypeDeclBaseRef : ContainerDeclRef + { + SLANG_DECLARE_DECL_REF(AggTypeDeclBase); + }; - // An extension to apply to an existing type - class ExtensionDecl : public AggTypeDeclBase - { - public: - TypeExp targetType; + // An extension to apply to an existing type + class ExtensionDecl : public AggTypeDeclBase + { + public: + TypeExp targetType; - // next extension attached to the same nominal type - ExtensionDecl* nextCandidateExtension = nullptr; + // next extension attached to the same nominal type + ExtensionDecl* nextCandidateExtension = nullptr; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct ExtensionDeclRef : AggTypeDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ExtensionDecl); + struct ExtensionDeclRef : AggTypeDeclBaseRef + { + SLANG_DECLARE_DECL_REF(ExtensionDecl); - RefPtr GetTargetType() const { return Substitute(GetDecl()->targetType); } - }; + RefPtr GetTargetType() const { return Substitute(GetDecl()->targetType); } + }; - // Declaration of a type that represents some sort of aggregate - class AggTypeDecl : public AggTypeDeclBase - { - public: + // Declaration of a type that represents some sort of aggregate + class AggTypeDecl : public AggTypeDeclBase + { + public: - // extensions that might apply to this declaration - ExtensionDecl* candidateExtensions = nullptr; - FilteredMemberList GetFields() - { - return GetMembersOfType(); - } - StructField* FindField(String name) + // extensions that might apply to this declaration + ExtensionDecl* candidateExtensions = nullptr; + FilteredMemberList GetFields() + { + return GetMembersOfType(); + } + StructField* FindField(String name) + { + for (auto field : GetFields()) { - for (auto field : GetFields()) - { - if (field->Name.Content == name) - return field.Ptr(); - } - return nullptr; + if (field->Name.Content == name) + return field.Ptr(); } - int FindFieldIndex(String name) + return nullptr; + } + int FindFieldIndex(String name) + { + int index = 0; + for (auto field : GetFields()) { - int index = 0; - for (auto field : GetFields()) - { - if (field->Name.Content == name) - return index; - index++; - } - return -1; + if (field->Name.Content == name) + return index; + index++; } - }; + return -1; + } + }; - struct AggTypeDeclRef : public AggTypeDeclBaseRef - { - SLANG_DECLARE_DECL_REF(AggTypeDecl); + struct AggTypeDeclRef : public AggTypeDeclBaseRef + { + SLANG_DECLARE_DECL_REF(AggTypeDecl); - ExtensionDecl* GetCandidateExtensions() const { return GetDecl()->candidateExtensions; } - }; + ExtensionDecl* GetCandidateExtensions() const { return GetDecl()->candidateExtensions; } + }; - class StructSyntaxNode : public AggTypeDecl - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class StructSyntaxNode : public AggTypeDecl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct StructDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(StructSyntaxNode); + struct StructDeclRef : public AggTypeDeclRef + { + SLANG_DECLARE_DECL_REF(StructSyntaxNode); - FilteredMemberRefList GetFields() const { return GetMembersOfType(); } - }; + FilteredMemberRefList GetFields() const { return GetMembersOfType(); } + }; - class ClassSyntaxNode : public AggTypeDecl - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class ClassSyntaxNode : public AggTypeDecl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct ClassDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(ClassSyntaxNode); + struct ClassDeclRef : public AggTypeDeclRef + { + SLANG_DECLARE_DECL_REF(ClassSyntaxNode); - FilteredMemberRefList GetFields() const { return GetMembersOfType(); } - }; + FilteredMemberRefList GetFields() const { return GetMembersOfType(); } + }; - // An interface which other types can conform to - class InterfaceDecl : public AggTypeDecl - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // An interface which other types can conform to + class InterfaceDecl : public AggTypeDecl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct InterfaceDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(InterfaceDecl); - }; + struct InterfaceDeclRef : public AggTypeDeclRef + { + SLANG_DECLARE_DECL_REF(InterfaceDecl); + }; - // A kind of pseudo-member that represents an explicit - // or implicit inheritance relationship. - // - class InheritanceDecl : public Decl - { - public: - // The type expression as written - TypeExp base; + // A kind of pseudo-member that represents an explicit + // or implicit inheritance relationship. + // + class InheritanceDecl : public Decl + { + public: + // The type expression as written + TypeExp base; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct InheritanceDeclRef : public DeclRef - { - SLANG_DECLARE_DECL_REF(InheritanceDecl); + struct InheritanceDeclRef : public DeclRef + { + SLANG_DECLARE_DECL_REF(InheritanceDecl); - RefPtr getBaseType() { return Substitute(GetDecl()->base.type); } - }; + RefPtr getBaseType() { return Substitute(GetDecl()->base.type); } + }; - // TODO: may eventually need sub-classes for explicit/direct vs. implicit/indirect inheritance + // TODO: may eventually need sub-classes for explicit/direct vs. implicit/indirect inheritance - // A declaration that represents a simple (non-aggregate) type - class SimpleTypeDecl : public Decl - { - }; + // A declaration that represents a simple (non-aggregate) type + class SimpleTypeDecl : public Decl + { + }; - struct SimpleTypeDeclRef : DeclRef - { - SLANG_DECLARE_DECL_REF(SimpleTypeDecl) - }; + struct SimpleTypeDeclRef : DeclRef + { + SLANG_DECLARE_DECL_REF(SimpleTypeDecl) + }; - // A `typedef` declaration - class TypeDefDecl : public SimpleTypeDecl - { - public: - TypeExp Type; + // A `typedef` declaration + class TypeDefDecl : public SimpleTypeDecl + { + public: + TypeExp Type; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct TypeDefDeclRef : SimpleTypeDeclRef - { - SLANG_DECLARE_DECL_REF(TypeDefDecl); + struct TypeDefDeclRef : SimpleTypeDeclRef + { + SLANG_DECLARE_DECL_REF(TypeDefDecl); - RefPtr GetType() const { return Substitute(GetDecl()->Type); } - }; + RefPtr GetType() const { return Substitute(GetDecl()->Type); } + }; - // A type alias of some kind (e.g., via `typedef`) - class NamedExpressionType : public ExpressionType - { - public: - NamedExpressionType(TypeDefDeclRef declRef) - : declRef(declRef) - {} + // A type alias of some kind (e.g., via `typedef`) + class NamedExpressionType : public ExpressionType + { + public: + NamedExpressionType(TypeDefDeclRef declRef) + : declRef(declRef) + {} - TypeDefDeclRef declRef; + TypeDefDeclRef declRef; - virtual String ToString() override; + virtual String ToString() override; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - class StatementSyntaxNode : public ModifiableSyntaxNode - { - public: - }; + class StatementSyntaxNode : public ModifiableSyntaxNode + { + public: + }; - // A scope for local declarations (e.g., as part of a statement) - class ScopeDecl : public ContainerDecl - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // A scope for local declarations (e.g., as part of a statement) + class ScopeDecl : public ContainerDecl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class ScopeStmt : public StatementSyntaxNode - { - public: - RefPtr scopeDecl; - }; + class ScopeStmt : public StatementSyntaxNode + { + public: + RefPtr scopeDecl; + }; - class BlockStatementSyntaxNode : public ScopeStmt - { - public: - List> Statements; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class BlockStatementSyntaxNode : public ScopeStmt + { + public: + List> Statements; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class UnparsedStmt : public StatementSyntaxNode - { - public: - // The tokens that were contained between `{` and `}` - List tokens; + class UnparsedStmt : public StatementSyntaxNode + { + public: + // The tokens that were contained between `{` and `}` + List tokens; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; - - class ParameterSyntaxNode : public VarDeclBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct ParamDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ParameterSyntaxNode); - }; + class ParameterSyntaxNode : public VarDeclBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // Base class for things that have parameter lists and can thus be applied to arguments ("called") - class CallableDecl : public ContainerDecl - { - public: - FilteredMemberList GetParameters() - { - return GetMembersOfType(); - } - TypeExp ReturnType; - }; + struct ParamDeclRef : VarDeclBaseRef + { + SLANG_DECLARE_DECL_REF(ParameterSyntaxNode); + }; - struct CallableDeclRef : ContainerDeclRef + // Base class for things that have parameter lists and can thus be applied to arguments ("called") + class CallableDecl : public ContainerDecl + { + public: + FilteredMemberList GetParameters() { - SLANG_DECLARE_DECL_REF(CallableDecl); - - RefPtr GetResultType() const - { - return Substitute(GetDecl()->ReturnType.type.Ptr()); - } - - FilteredMemberRefList GetParameters() - { - return GetMembersOfType(); - } - }; + return GetMembersOfType(); + } + TypeExp ReturnType; + }; - // Base class for callable things that may also have a body that is evaluated to produce their result - class FunctionDeclBase : public CallableDecl - { - public: - RefPtr Body; - }; + struct CallableDeclRef : ContainerDeclRef + { + SLANG_DECLARE_DECL_REF(CallableDecl); - struct FuncDeclBaseRef : CallableDeclRef + RefPtr GetResultType() const { - SLANG_DECLARE_DECL_REF(FunctionDeclBase); - }; + return Substitute(GetDecl()->ReturnType.type.Ptr()); + } - // Function types are currently used for references to symbols that name - // either ordinary functions, or "component functions." - // We do not directly store a representation of the type, and instead - // use a reference to the symbol to stand in for its logical type - class FuncType : public ExpressionType + FilteredMemberRefList GetParameters() { - public: - CallableDeclRef declRef; + return GetMembersOfType(); + } + }; - virtual String ToString() override; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + // Base class for callable things that may also have a body that is evaluated to produce their result + class FunctionDeclBase : public CallableDecl + { + public: + RefPtr Body; + }; - // A constructor/initializer to create instances of a type - class ConstructorDecl : public FunctionDeclBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + struct FuncDeclBaseRef : CallableDeclRef + { + SLANG_DECLARE_DECL_REF(FunctionDeclBase); + }; + + // Function types are currently used for references to symbols that name + // either ordinary functions, or "component functions." + // We do not directly store a representation of the type, and instead + // use a reference to the symbol to stand in for its logical type + class FuncType : public ExpressionType + { + public: + CallableDeclRef declRef; + + virtual String ToString() override; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; + + // A constructor/initializer to create instances of a type + class ConstructorDecl : public FunctionDeclBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct ConstructorDeclRef : FuncDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ConstructorDecl); - }; + struct ConstructorDeclRef : FuncDeclBaseRef + { + SLANG_DECLARE_DECL_REF(ConstructorDecl); + }; - // A subscript operation used to index instances of a type - class SubscriptDecl : public CallableDecl - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // A subscript operation used to index instances of a type + class SubscriptDecl : public CallableDecl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct SubscriptDeclRef : CallableDeclRef - { - SLANG_DECLARE_DECL_REF(SubscriptDecl); - }; + struct SubscriptDeclRef : CallableDeclRef + { + SLANG_DECLARE_DECL_REF(SubscriptDecl); + }; - // An "accessor" for a subscript or property - class AccessorDecl : public FunctionDeclBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // An "accessor" for a subscript or property + class AccessorDecl : public FunctionDeclBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class GetterDecl : public AccessorDecl - { - }; + class GetterDecl : public AccessorDecl + { + }; - class SetterDecl : public AccessorDecl - { - }; + class SetterDecl : public AccessorDecl + { + }; - // + // - class FunctionSyntaxNode : public FunctionDeclBase - { - public: - String InternalName; - bool IsInline() { return HasModifier(); } - bool IsExtern() { return HasModifier(); } - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - FunctionSyntaxNode() - { - } - }; - - struct FuncDeclRef : FuncDeclBaseRef + class FunctionSyntaxNode : public FunctionDeclBase + { + public: + String InternalName; + bool IsInline() { return HasModifier(); } + bool IsExtern() { return HasModifier(); } + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + FunctionSyntaxNode() { - SLANG_DECLARE_DECL_REF(FunctionSyntaxNode); - }; + } + }; + struct FuncDeclRef : FuncDeclBaseRef + { + SLANG_DECLARE_DECL_REF(FunctionSyntaxNode); + }; - struct Scope : public RefObject - { - // The parent of this scope (where lookup should go if nothing is found locally) - RefPtr parent; - // The next sibling of this scope (a peer for lookup) - RefPtr nextSibling; + struct Scope : public RefObject + { + // The parent of this scope (where lookup should go if nothing is found locally) + RefPtr parent; - // 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; - }; + // The next sibling of this scope (a peer for lookup) + RefPtr nextSibling; - // Base class for expressions that will reference declarations - class DeclRefExpr : public ExpressionSyntaxNode - { - public: - // The scope in which to perform lookup - RefPtr scope; + // 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; + }; + + // Base class for expressions that will reference declarations + class DeclRefExpr : public ExpressionSyntaxNode + { + public: + // The scope in which to perform lookup + RefPtr scope; - // The declaration of the symbol being referenced - DeclRef declRef; - }; + // The declaration of the symbol being referenced + DeclRef declRef; + }; - class VarExpressionSyntaxNode : public DeclRefExpr - { - public: - // The name of the symbol being referenced - String Variable; + class VarExpressionSyntaxNode : public DeclRefExpr + { + public: + // The name of the symbol being referenced + String Variable; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // Masks to be applied when lookup up declarations - enum class LookupMask : uint8_t - { - Type = 0x1, - Function = 0x2, - Value = 0x4, + // Masks to be applied when lookup up declarations + enum class LookupMask : uint8_t + { + Type = 0x1, + Function = 0x2, + Value = 0x4, - All = Type | Function | Value, - }; + All = Type | Function | Value, + }; - // Represents one item found during lookup - struct LookupResultItem + // 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. + class Breadcrumb : public RefObject { - // 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. - class Breadcrumb : public RefObject + public: + enum class Kind { - public: - enum class Kind - { - Member, // A member was references - Deref, // A value with pointer(-like) type was dereferenced - }; - - Kind kind; - DeclRef declRef; - RefPtr next; - - Breadcrumb(Kind kind, DeclRef declRef, RefPtr next) - : kind(kind) - , declRef(declRef) - , next(next) - {} + Member, // A member was references + Deref, // A value with pointer(-like) type was dereferenced }; - // A properly-specialized reference to the declaration that was found. + Kind kind; DeclRef declRef; + RefPtr next; - // 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 breadcrumbs; - - LookupResultItem() = default; - explicit LookupResultItem(DeclRef declRef) - : declRef(declRef) - {} - LookupResultItem(DeclRef declRef, RefPtr breadcrumbs) - : declRef(declRef) - , breadcrumbs(breadcrumbs) + Breadcrumb(Kind kind, DeclRef declRef, RefPtr next) + : kind(kind) + , declRef(declRef) + , next(next) {} }; + // A properly-specialized reference to the declaration that was found. + DeclRef declRef; - // 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; + // 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 breadcrumbs; + + LookupResultItem() = default; + explicit LookupResultItem(DeclRef declRef) + : declRef(declRef) + {} + LookupResultItem(DeclRef declRef, RefPtr 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 items; + // 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 items; - // Was at least one result found? - bool isValid() const { return item.declRef.GetDecl() != nullptr; } + // Was at least one result found? + bool isValid() const { return item.declRef.GetDecl() != nullptr; } - bool isOverloaded() const { return items.Count() > 1; } - }; + bool isOverloaded() const { return items.Count() > 1; } + }; - struct LookupRequest - { - RefPtr scope = nullptr; - RefPtr endScope = nullptr; + struct LookupRequest + { + RefPtr scope = nullptr; + RefPtr endScope = nullptr; - LookupMask mask = LookupMask::All; - }; + LookupMask mask = LookupMask::All; + }; - // An expression that references an overloaded set of declarations - // having the same name. - class OverloadedExpr : public ExpressionSyntaxNode - { - public: - // Optional: the base expression is this overloaded result - // arose from a member-reference expression. - RefPtr base; + // An expression that references an overloaded set of declarations + // having the same name. + class OverloadedExpr : public ExpressionSyntaxNode + { + public: + // Optional: the base expression is this overloaded result + // arose from a member-reference expression. + RefPtr base; - // The lookup result that was ambiguous - LookupResult lookupResult2; + // The lookup result that was ambiguous + LookupResult lookupResult2; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - typedef double FloatingPointLiteralValue; + typedef double FloatingPointLiteralValue; - class ConstantExpressionSyntaxNode : public ExpressionSyntaxNode + class ConstantExpressionSyntaxNode : public ExpressionSyntaxNode + { + public: + enum class ConstantType { - public: - enum class ConstantType - { - Int, Bool, Float - }; - ConstantType ConstType; - union - { - int IntValue; - FloatingPointLiteralValue FloatValue; - }; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; + Int, Bool, Float }; - - enum class Operator - { - Neg, Not, BitNot, PreInc, PreDec, PostInc, PostDec, - Mul, Div, Mod, - Add, Sub, - Lsh, Rsh, - Eql, Neq, Greater, Less, Geq, Leq, - BitAnd, BitXor, BitOr, - And, - Or, - Sequence, - Select, - Assign = 200, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, - LshAssign, RshAssign, OrAssign, AndAssign, XorAssign, + ConstantType ConstType; + union + { + int IntValue; + FloatingPointLiteralValue FloatValue; }; - String GetOperatorFunctionName(Operator op); - String OperatorToString(Operator op); + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // An initializer list, e.g. `{ 1, 2, 3 }` - class InitializerListExpr : public ExpressionSyntaxNode - { - public: - List> args; + enum class Operator + { + Neg, Not, BitNot, PreInc, PreDec, PostInc, PostDec, + Mul, Div, Mod, + Add, Sub, + Lsh, Rsh, + Eql, Neq, Greater, Less, Geq, Leq, + BitAnd, BitXor, BitOr, + And, + Or, + Sequence, + Select, + Assign = 200, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, + LshAssign, RshAssign, OrAssign, AndAssign, XorAssign, + }; + String GetOperatorFunctionName(Operator op); + String OperatorToString(Operator op); + + // An initializer list, e.g. `{ 1, 2, 3 }` + class InitializerListExpr : public ExpressionSyntaxNode + { + public: + List> args; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // A base expression being applied to arguments: covers - // both ordinary `()` function calls and `<>` generic application - class AppExprBase : public ExpressionSyntaxNode - { - public: - RefPtr FunctionExpr; - List> Arguments; - }; + // A base expression being applied to arguments: covers + // both ordinary `()` function calls and `<>` generic application + class AppExprBase : public ExpressionSyntaxNode + { + public: + RefPtr FunctionExpr; + List> Arguments; + }; - class InvokeExpressionSyntaxNode : public AppExprBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class InvokeExpressionSyntaxNode : public AppExprBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class OperatorExpressionSyntaxNode : public InvokeExpressionSyntaxNode - { - public: + class OperatorExpressionSyntaxNode : public InvokeExpressionSyntaxNode + { + public: // Operator Operator; -// void SetOperator(RefPtr scope, Slang::Compiler::Operator op); - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; +// void SetOperator(RefPtr scope, Slang::Operator op); + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class InfixExpr : public OperatorExpressionSyntaxNode {}; - class PrefixExpr : public OperatorExpressionSyntaxNode {}; - class PostfixExpr : public OperatorExpressionSyntaxNode {}; + class InfixExpr : public OperatorExpressionSyntaxNode {}; + class PrefixExpr : public OperatorExpressionSyntaxNode {}; + class PostfixExpr : public OperatorExpressionSyntaxNode {}; - class IndexExpressionSyntaxNode : public ExpressionSyntaxNode - { - public: - RefPtr BaseExpression; - RefPtr IndexExpression; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class IndexExpressionSyntaxNode : public ExpressionSyntaxNode + { + public: + RefPtr BaseExpression; + RefPtr IndexExpression; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class MemberExpressionSyntaxNode : public DeclRefExpr - { - public: - RefPtr BaseExpression; - String MemberName; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class MemberExpressionSyntaxNode : public DeclRefExpr + { + public: + RefPtr BaseExpression; + String MemberName; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class SwizzleExpr : public ExpressionSyntaxNode - { - public: - RefPtr base; - int elementCount; - int elementIndices[4]; + class SwizzleExpr : public ExpressionSyntaxNode + { + public: + RefPtr base; + int elementCount; + int elementIndices[4]; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // A dereference of a pointer or pointer-like type - class DerefExpr : public ExpressionSyntaxNode - { - public: - RefPtr base; + // A dereference of a pointer or pointer-like type + class DerefExpr : public ExpressionSyntaxNode + { + public: + RefPtr base; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class TypeCastExpressionSyntaxNode : public ExpressionSyntaxNode - { - public: - TypeExp TargetType; - RefPtr Expression; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class TypeCastExpressionSyntaxNode : public ExpressionSyntaxNode + { + public: + TypeExp TargetType; + RefPtr Expression; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class SelectExpressionSyntaxNode : public OperatorExpressionSyntaxNode - { - public: - }; + class SelectExpressionSyntaxNode : public OperatorExpressionSyntaxNode + { + public: + }; - class EmptyStatementSyntaxNode : public StatementSyntaxNode - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class EmptyStatementSyntaxNode : public StatementSyntaxNode + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class DiscardStatementSyntaxNode : public StatementSyntaxNode - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class DiscardStatementSyntaxNode : public StatementSyntaxNode + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct Variable : public VarDeclBase - { - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + struct Variable : public VarDeclBase + { + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class VarDeclrStatementSyntaxNode : public StatementSyntaxNode + class VarDeclrStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr decl; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + // A "module" of code (essentiately, a single translation unit) + // that provides a scope for some number of declarations. + class ProgramSyntaxNode : public ContainerDecl + { + public: + // Access members of specific types + FilteredMemberList GetFunctions() { - public: - RefPtr decl; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + return GetMembersOfType(); + } - // A "module" of code (essentiately, a single translation unit) - // that provides a scope for some number of declarations. - class ProgramSyntaxNode : public ContainerDecl + FilteredMemberList GetClasses() { - public: - // Access members of specific types - FilteredMemberList GetFunctions() - { - return GetMembersOfType(); - } + return GetMembersOfType(); + } + FilteredMemberList GetStructs() + { + return GetMembersOfType(); + } + FilteredMemberList GetTypeDefs() + { + return GetMembersOfType(); + } - FilteredMemberList GetClasses() - { - return GetMembersOfType(); - } - FilteredMemberList GetStructs() - { - return GetMembersOfType(); - } - FilteredMemberList GetTypeDefs() - { - return GetMembersOfType(); - } + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class ImportDecl : public Decl + { + public: + // The name of the module we are trying to import + Token nameToken; - class ImportDecl : public Decl - { - public: - // The name of the module we are trying to import - Token nameToken; + // The scope that we want to import into + RefPtr scope; - // The scope that we want to import into - RefPtr scope; + // The module that actually got imported + RefPtr importedModuleDecl; - // The module that actually got imported - RefPtr importedModuleDecl; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class IfStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr Predicate; + RefPtr PositiveStatement; + RefPtr NegativeStatement; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + // A statement that can be escaped with a `break` + class BreakableStmt : public ScopeStmt + {}; + + class SwitchStmt : public BreakableStmt + { + public: + RefPtr condition; + RefPtr body; - class IfStatementSyntaxNode : public StatementSyntaxNode - { - public: - RefPtr Predicate; - RefPtr PositiveStatement; - RefPtr NegativeStatement; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // A statement that can be escaped with a `break` - class BreakableStmt : public ScopeStmt - {}; + // A statement that is expected to appear lexically nested inside + // some other construct, and thus needs to keep track of the + // outer statement that it is associated with... + class ChildStmt : public StatementSyntaxNode + { + public: + StatementSyntaxNode* parentStmt = nullptr; + }; + + // a `case` or `default` statement inside a `switch` + // + // Note(tfoley): A correct AST for a C-like language would treat + // these as a labelled statement, and so they would contain a + // sub-statement. I'm leaving that out for now for simplicity. + class CaseStmtBase : public ChildStmt + { + public: + }; - class SwitchStmt : public BreakableStmt - { - public: - RefPtr condition; - RefPtr body; + // a `case` statement inside a `switch` + class CaseStmt : public CaseStmtBase + { + public: + RefPtr expr; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // A statement that is expected to appear lexically nested inside - // some other construct, and thus needs to keep track of the - // outer statement that it is associated with... - class ChildStmt : public StatementSyntaxNode - { - public: - StatementSyntaxNode* parentStmt = nullptr; - }; + // a `default` statement inside a `switch` + class DefaultStmt : public CaseStmtBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // a `case` or `default` statement inside a `switch` - // - // Note(tfoley): A correct AST for a C-like language would treat - // these as a labelled statement, and so they would contain a - // sub-statement. I'm leaving that out for now for simplicity. - class CaseStmtBase : public ChildStmt - { - public: - }; + // A statement that represents a loop, and can thus be escaped with a `continue` + class LoopStmt : public BreakableStmt + {}; - // a `case` statement inside a `switch` - class CaseStmt : public CaseStmtBase - { - public: - RefPtr expr; + class ForStatementSyntaxNode : public LoopStmt + { + public: + RefPtr InitialStatement; + RefPtr SideEffectExpression, PredicateExpression; + RefPtr Statement; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + class WhileStatementSyntaxNode : public LoopStmt + { + public: + RefPtr Predicate; + RefPtr Statement; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class DoWhileStatementSyntaxNode : public LoopStmt + { + public: + RefPtr Statement; + RefPtr Predicate; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + // The case of child statements that do control flow relative + // to their parent statement. + class JumpStmt : public ChildStmt + { + public: + StatementSyntaxNode* parentStmt = nullptr; + }; - // a `default` statement inside a `switch` - class DefaultStmt : public CaseStmtBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class BreakStatementSyntaxNode : public JumpStmt + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // A statement that represents a loop, and can thus be escaped with a `continue` - class LoopStmt : public BreakableStmt - {}; + class ContinueStatementSyntaxNode : public JumpStmt + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class ForStatementSyntaxNode : public LoopStmt - { - public: - RefPtr InitialStatement; - RefPtr SideEffectExpression, PredicateExpression; - RefPtr Statement; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class ReturnStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr Expression; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class WhileStatementSyntaxNode : public LoopStmt - { - public: - RefPtr Predicate; - RefPtr Statement; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + class ExpressionStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr Expression; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + // Note(tfoley): Moved this further down in the file because it depends on + // `ExpressionSyntaxNode` and a forward reference just isn't good enough + // for `RefPtr`. + // + class GenericAppExpr : public AppExprBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class DoWhileStatementSyntaxNode : public LoopStmt - { - public: - RefPtr Statement; - RefPtr Predicate; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // An expression representing re-use of the syntax for a type in more + // than once conceptually-distinct declaration + class SharedTypeExpr : public ExpressionSyntaxNode + { + public: + // The underlying type expression that we want to share + TypeExp base; - // The case of child statements that do control flow relative - // to their parent statement. - class JumpStmt : public ChildStmt - { - public: - StatementSyntaxNode* parentStmt = nullptr; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - class BreakStatementSyntaxNode : public JumpStmt - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; - class ContinueStatementSyntaxNode : public JumpStmt - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // A modifier that indicates a built-in base type (e.g., `float`) + class BuiltinTypeModifier : public Modifier + { + public: + BaseType tag; + }; + + // A modifier that indicates a built-in type that isn't a base type (e.g., `vector`) + // + // TODO(tfoley): This deserves a better name than "magic" + class MagicTypeModifier : public Modifier + { + public: + String name; + uint32_t tag; + }; - class ReturnStatementSyntaxNode : public StatementSyntaxNode - { - public: - RefPtr Expression; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // Modifiers that affect the storage layout for matrices + class MatrixLayoutModifier : public Modifier {}; - class ExpressionStatementSyntaxNode : public StatementSyntaxNode - { - public: - RefPtr Expression; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // Modifiers that specify row- and column-major layout, respectively + class RowMajorLayoutModifier : public MatrixLayoutModifier {}; + class ColumnMajorLayoutModifier : public MatrixLayoutModifier {}; - // Note(tfoley): Moved this further down in the file because it depends on - // `ExpressionSyntaxNode` and a forward reference just isn't good enough - // for `RefPtr`. - // - class GenericAppExpr : public AppExprBase - { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // The HLSL flavor of those modifiers + class HLSLRowMajorLayoutModifier : public RowMajorLayoutModifier {}; + class HLSLColumnMajorLayoutModifier : public ColumnMajorLayoutModifier {}; - // An expression representing re-use of the syntax for a type in more - // than once conceptually-distinct declaration - class SharedTypeExpr : public ExpressionSyntaxNode - { - public: - // The underlying type expression that we want to share - TypeExp base; + // The GLSL flavor of those modifiers + // + // Note(tfoley): The GLSL versions of these modifiers are "backwards" + // in the sense that when a GLSL programmer requests row-major layout, + // we actually interpret that as requesting column-major. This makes + // sense because we interpret matrix conventions backwards from how + // GLSL specifies them. + class GLSLRowMajorLayoutModifier : public ColumnMajorLayoutModifier {}; + class GLSLColumnMajorLayoutModifier : public RowMajorLayoutModifier {}; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // More HLSL Keyword + // HLSL `nointerpolation` modifier + class HLSLNoInterpolationModifier : public Modifier {}; - // A modifier that indicates a built-in base type (e.g., `float`) - class BuiltinTypeModifier : public Modifier - { - public: - BaseType tag; - }; + // HLSL `linear` modifier + class HLSLLinearModifier : public Modifier {}; - // A modifier that indicates a built-in type that isn't a base type (e.g., `vector`) - // - // TODO(tfoley): This deserves a better name than "magic" - class MagicTypeModifier : public Modifier - { - public: - String name; - uint32_t tag; - }; + // HLSL `sample` modifier + class HLSLSampleModifier : public Modifier {}; - // Modifiers that affect the storage layout for matrices - class MatrixLayoutModifier : public Modifier {}; + // HLSL `centroid` modifier + class HLSLCentroidModifier : public Modifier {}; - // Modifiers that specify row- and column-major layout, respectively - class RowMajorLayoutModifier : public MatrixLayoutModifier {}; - class ColumnMajorLayoutModifier : public MatrixLayoutModifier {}; + // HLSL `precise` modifier + class HLSLPreciseModifier : public Modifier {}; - // The HLSL flavor of those modifiers - class HLSLRowMajorLayoutModifier : public RowMajorLayoutModifier {}; - class HLSLColumnMajorLayoutModifier : public ColumnMajorLayoutModifier {}; + // HLSL `shared` modifier (which is used by the effect system, + // and shouldn't be confused with `groupshared`) + class HLSLEffectSharedModifier : public Modifier {}; - // The GLSL flavor of those modifiers - // - // Note(tfoley): The GLSL versions of these modifiers are "backwards" - // in the sense that when a GLSL programmer requests row-major layout, - // we actually interpret that as requesting column-major. This makes - // sense because we interpret matrix conventions backwards from how - // GLSL specifies them. - class GLSLRowMajorLayoutModifier : public ColumnMajorLayoutModifier {}; - class GLSLColumnMajorLayoutModifier : public RowMajorLayoutModifier {}; + // HLSL `groupshared` modifier + class HLSLGroupSharedModifier : public Modifier {}; - // More HLSL Keyword + // HLSL `static` modifier (probably doesn't need to be + // treated as HLSL-specific) + class HLSLStaticModifier : public Modifier {}; - // HLSL `nointerpolation` modifier - class HLSLNoInterpolationModifier : public Modifier {}; + // HLSL `uniform` modifier (distinct meaning from GLSL + // use of the keyword) + class HLSLUniformModifier : public Modifier {}; - // HLSL `linear` modifier - class HLSLLinearModifier : public Modifier {}; + // HLSL `volatile` modifier (ignored) + class HLSLVolatileModifier : public Modifier {}; - // HLSL `sample` modifier - class HLSLSampleModifier : public Modifier {}; + // An HLSL `[name(arg0, ...)]` style attribute. + class HLSLAttribute : public Modifier + { + public: + Token nameToken; + List> args; + }; + + // An HLSL `[name(...)]` attribute that hasn't undergone + // any semantic analysis. + // After analysis, this might be transformed into a more specific case. + class HLSLUncheckedAttribute : public HLSLAttribute + { + public: + }; - // HLSL `centroid` modifier - class HLSLCentroidModifier : public Modifier {}; + // An HLSL `[numthreads(x,y,z)]` attribute + class HLSLNumThreadsAttribute : public HLSLAttribute + { + public: + // The number of threads to use along each axis + int32_t x; + int32_t y; + int32_t z; + }; + + // HLSL modifiers for geometry shader input topology + class HLSLGeometryShaderInputPrimitiveTypeModifier : public Modifier {}; + class HLSLPointModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; + class HLSLLineModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; + class HLSLTriangleModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; + class HLSLLineAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; + class HLSLTriangleAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; + + // + + // A generic declaration, parameterized on types/values + class GenericDecl : public ContainerDecl + { + public: + // The decl that is genericized... + RefPtr inner; - // HLSL `precise` modifier - class HLSLPreciseModifier : public Modifier {}; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - // HLSL `shared` modifier (which is used by the effect system, - // and shouldn't be confused with `groupshared`) - class HLSLEffectSharedModifier : public Modifier {}; + struct GenericDeclRef : ContainerDeclRef + { + SLANG_DECLARE_DECL_REF(GenericDecl); - // HLSL `groupshared` modifier - class HLSLGroupSharedModifier : public Modifier {}; + Decl* GetInner() const { return GetDecl()->inner.Ptr(); } + }; - // HLSL `static` modifier (probably doesn't need to be - // treated as HLSL-specific) - class HLSLStaticModifier : public Modifier {}; + // The "type" of an expression that names a generic declaration. + class GenericDeclRefType : public ExpressionType + { + public: + GenericDeclRefType(GenericDeclRef declRef) + : declRef(declRef) + {} - // HLSL `uniform` modifier (distinct meaning from GLSL - // use of the keyword) - class HLSLUniformModifier : public Modifier {}; + GenericDeclRef declRef; + GenericDeclRef const& GetDeclRef() const { return declRef; } - // HLSL `volatile` modifier (ignored) - class HLSLVolatileModifier : public Modifier {}; + virtual String ToString() override; - // An HLSL `[name(arg0, ...)]` style attribute. - class HLSLAttribute : public Modifier - { - public: - Token nameToken; - List> args; - }; - - // An HLSL `[name(...)]` attribute that hasn't undergone - // any semantic analysis. - // After analysis, this might be transformed into a more specific case. - class HLSLUncheckedAttribute : public HLSLAttribute - { - public: - }; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual int GetHashCode() override; + virtual ExpressionType* CreateCanonicalType() override; + }; - // An HLSL `[numthreads(x,y,z)]` attribute - class HLSLNumThreadsAttribute : public HLSLAttribute - { - public: - // The number of threads to use along each axis - int32_t x; - int32_t y; - int32_t z; - }; - // HLSL modifiers for geometry shader input topology - class HLSLGeometryShaderInputPrimitiveTypeModifier : public Modifier {}; - class HLSLPointModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; - class HLSLLineModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; - class HLSLTriangleModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; - class HLSLLineAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; - class HLSLTriangleAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier {}; - // + class GenericTypeParamDecl : public SimpleTypeDecl + { + public: + // The bound for the type parameter represents a trait that any + // type used as this parameter must conform to +// TypeExp bound; - // A generic declaration, parameterized on types/values - class GenericDecl : public ContainerDecl - { - public: - // The decl that is genericized... - RefPtr inner; + // The "initializer" for the parameter represents a default value + TypeExp initType; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - struct GenericDeclRef : ContainerDeclRef - { - SLANG_DECLARE_DECL_REF(GenericDecl); + struct GenericTypeParamDeclRef : SimpleTypeDeclRef + { + SLANG_DECLARE_DECL_REF(GenericTypeParamDecl); + }; - Decl* GetInner() const { return GetDecl()->inner.Ptr(); } - }; + // A constraint placed as part of a generic declaration + class GenericTypeConstraintDecl : public Decl + { + public: + // A type constraint like `T : U` is constraining `T` to be "below" `U` + // on a lattice of types. This may not be a subtyping relationship + // per se, but it makes sense to use that terminology here, so we + // think of these fields as the sub-type and sup-ertype, respectively. + TypeExp sub; + TypeExp sup; + + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + struct GenericTypeConstraintDeclRef : DeclRef + { + SLANG_DECLARE_DECL_REF(GenericTypeConstraintDecl); - // The "type" of an expression that names a generic declaration. - class GenericDeclRefType : public ExpressionType - { - public: - GenericDeclRefType(GenericDeclRef declRef) - : declRef(declRef) - {} + RefPtr GetSub() { return Substitute(GetDecl()->sub); } + RefPtr GetSup() { return Substitute(GetDecl()->sup); } + }; - GenericDeclRef declRef; - GenericDeclRef const& GetDeclRef() const { return declRef; } - virtual String ToString() override; + class GenericValueParamDecl : public VarDeclBase + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual int GetHashCode() override; - virtual ExpressionType* CreateCanonicalType() override; - }; + struct GenericValueParamDeclRef : VarDeclBaseRef + { + SLANG_DECLARE_DECL_REF(GenericValueParamDecl); + }; + // The logical "value" of a rererence to a generic value parameter + class GenericParamIntVal : public IntVal + { + public: + VarDeclBaseRef declRef; + GenericParamIntVal(VarDeclBaseRef declRef) + : declRef(declRef) + {} - class GenericTypeParamDecl : public SimpleTypeDecl - { - public: - // The bound for the type parameter represents a trait that any - // type used as this parameter must conform to -// TypeExp bound; + virtual bool EqualsVal(Val* val) override; + virtual String ToString() override; + virtual int GetHashCode() override; + virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; + }; - // The "initializer" for the parameter represents a default value - TypeExp initType; + // Declaration of a user-defined modifier + class ModifierDecl : public Decl + { + public: + // The name of the C++ class to instantiate + // (this is a reference to a class in the compiler source code, + // and not the user's source code) + Token classNameToken; + + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; + + // An empty declaration (which might still have modifiers attached). + // + // An empty declaration is uncommon in HLSL, but + // in GLSL it is often used at the global scope + // to declare metadata that logically belongs + // to the entry point, e.g.: + // + // layout(local_size_x = 16) in; + // + class EmptyDecl : public Decl + { + public: + virtual RefPtr Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + // - struct GenericTypeParamDeclRef : SimpleTypeDeclRef - { - SLANG_DECLARE_DECL_REF(GenericTypeParamDecl); - }; + class SyntaxVisitor : public Object + { + protected: + DiagnosticSink * sink = nullptr; + DiagnosticSink* getSink() { return sink; } - // A constraint placed as part of a generic declaration - class GenericTypeConstraintDecl : public Decl + SourceLanguage sourceLanguage = SourceLanguage::Unknown; + public: + void setSourceLanguage(SourceLanguage language) { - public: - // A type constraint like `T : U` is constraining `T` to be "below" `U` - // on a lattice of types. This may not be a subtyping relationship - // per se, but it makes sense to use that terminology here, so we - // think of these fields as the sub-type and sup-ertype, respectively. - TypeExp sub; - TypeExp sup; - - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; + sourceLanguage = language; + } - struct GenericTypeConstraintDeclRef : DeclRef + SyntaxVisitor(DiagnosticSink * sink) + : sink(sink) + {} + virtual RefPtr VisitProgram(ProgramSyntaxNode* program) { - SLANG_DECLARE_DECL_REF(GenericTypeConstraintDecl); - - RefPtr GetSub() { return Substitute(GetDecl()->sub); } - RefPtr GetSup() { return Substitute(GetDecl()->sup); } - }; + for (auto & m : program->Members) + m = m->Accept(this).As(); + return program; + } + virtual void visitImportDecl(ImportDecl * decl) = 0; - class GenericValueParamDecl : public VarDeclBase + virtual RefPtr VisitFunction(FunctionSyntaxNode* func) { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; - - struct GenericValueParamDeclRef : VarDeclBaseRef + func->ReturnType = func->ReturnType.Accept(this); + for (auto & member : func->Members) + member = member->Accept(this).As(); + if (func->Body) + func->Body = func->Body->Accept(this).As(); + return func; + } + virtual RefPtr VisitScopeDecl(ScopeDecl* decl) { - SLANG_DECLARE_DECL_REF(GenericValueParamDecl); - }; - - // The logical "value" of a rererence to a generic value parameter - class GenericParamIntVal : public IntVal + // By default don't visit children, because they will always + // be encountered in the ordinary flow of the corresponding statement. + return decl; + } + virtual RefPtr VisitStruct(StructSyntaxNode * s) { - public: - VarDeclBaseRef declRef; - - GenericParamIntVal(VarDeclBaseRef declRef) - : declRef(declRef) - {} - - virtual bool EqualsVal(Val* val) override; - virtual String ToString() override; - virtual int GetHashCode() override; - virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; - }; - - // Declaration of a user-defined modifier - class ModifierDecl : public Decl + for (auto & f : s->Members) + f = f->Accept(this).As(); + return s; + } + virtual RefPtr VisitClass(ClassSyntaxNode * s) { - public: - // The name of the C++ class to instantiate - // (this is a reference to a class in the compiler source code, - // and not the user's source code) - Token classNameToken; - - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; - - // An empty declaration (which might still have modifiers attached). - // - // An empty declaration is uncommon in HLSL, but - // in GLSL it is often used at the global scope - // to declare metadata that logically belongs - // to the entry point, e.g.: - // - // layout(local_size_x = 16) in; - // - class EmptyDecl : public Decl + for (auto & f : s->Members) + f = f->Accept(this).As(); + return s; + } + virtual RefPtr VisitGenericDecl(GenericDecl * decl) { - public: - virtual RefPtr Accept(SyntaxVisitor * visitor) override; - }; - - // - - class SyntaxVisitor : public Object + for (auto & m : decl->Members) + m = m->Accept(this).As(); + decl->inner = decl->inner->Accept(this).As(); + return decl; + } + virtual RefPtr VisitTypeDefDecl(TypeDefDecl* decl) { - protected: - DiagnosticSink * sink = nullptr; - DiagnosticSink* getSink() { return sink; } - - SourceLanguage sourceLanguage = SourceLanguage::Unknown; - public: - void setSourceLanguage(SourceLanguage language) - { - sourceLanguage = language; - } - - SyntaxVisitor(DiagnosticSink * sink) - : sink(sink) - {} - virtual RefPtr VisitProgram(ProgramSyntaxNode* program) - { - for (auto & m : program->Members) - m = m->Accept(this).As(); - return program; - } - - virtual void visitImportDecl(ImportDecl * decl) = 0; - - virtual RefPtr VisitFunction(FunctionSyntaxNode* func) - { - func->ReturnType = func->ReturnType.Accept(this); - for (auto & member : func->Members) - member = member->Accept(this).As(); - if (func->Body) - func->Body = func->Body->Accept(this).As(); - return func; - } - virtual RefPtr VisitScopeDecl(ScopeDecl* decl) - { - // By default don't visit children, because they will always - // be encountered in the ordinary flow of the corresponding statement. - return decl; - } - virtual RefPtr VisitStruct(StructSyntaxNode * s) - { - for (auto & f : s->Members) - f = f->Accept(this).As(); - return s; - } - virtual RefPtr VisitClass(ClassSyntaxNode * s) - { - for (auto & f : s->Members) - f = f->Accept(this).As(); - return s; - } - virtual RefPtr VisitGenericDecl(GenericDecl * decl) - { - for (auto & m : decl->Members) - m = m->Accept(this).As(); - decl->inner = decl->inner->Accept(this).As(); - return decl; - } - virtual RefPtr VisitTypeDefDecl(TypeDefDecl* decl) - { - decl->Type = decl->Type.Accept(this); - return decl; - } - virtual RefPtr VisitDiscardStatement(DiscardStatementSyntaxNode * stmt) - { - return stmt; - } - virtual RefPtr VisitStructField(StructField * f) - { - f->Type = f->Type.Accept(this); - return f; - } - virtual RefPtr VisitBlockStatement(BlockStatementSyntaxNode* stmt) - { - for (auto & s : stmt->Statements) - s = s->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitBreakStatement(BreakStatementSyntaxNode* stmt) - { - return stmt; - } - virtual RefPtr VisitContinueStatement(ContinueStatementSyntaxNode* stmt) - { - return stmt; - } + decl->Type = decl->Type.Accept(this); + return decl; + } + virtual RefPtr VisitDiscardStatement(DiscardStatementSyntaxNode * stmt) + { + return stmt; + } + virtual RefPtr VisitStructField(StructField * f) + { + f->Type = f->Type.Accept(this); + return f; + } + virtual RefPtr VisitBlockStatement(BlockStatementSyntaxNode* stmt) + { + for (auto & s : stmt->Statements) + s = s->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitBreakStatement(BreakStatementSyntaxNode* stmt) + { + return stmt; + } + virtual RefPtr VisitContinueStatement(ContinueStatementSyntaxNode* stmt) + { + return stmt; + } - virtual RefPtr VisitDoWhileStatement(DoWhileStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitEmptyStatement(EmptyStatementSyntaxNode* stmt) - { - return stmt; - } - virtual RefPtr VisitForStatement(ForStatementSyntaxNode* stmt) - { - if (stmt->InitialStatement) - stmt->InitialStatement = stmt->InitialStatement->Accept(this).As(); - if (stmt->PredicateExpression) - stmt->PredicateExpression = stmt->PredicateExpression->Accept(this).As(); - if (stmt->SideEffectExpression) - stmt->SideEffectExpression = stmt->SideEffectExpression->Accept(this).As(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitIfStatement(IfStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As(); - if (stmt->PositiveStatement) - stmt->PositiveStatement = stmt->PositiveStatement->Accept(this).As(); - if (stmt->NegativeStatement) - stmt->NegativeStatement = stmt->NegativeStatement->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitSwitchStmt(SwitchStmt* stmt) - { - if (stmt->condition) - stmt->condition = stmt->condition->Accept(this).As(); - if (stmt->body) - stmt->body = stmt->body->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitCaseStmt(CaseStmt* stmt) - { - if (stmt->expr) - stmt->expr = stmt->expr->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitDefaultStmt(DefaultStmt* stmt) - { - return stmt; - } - virtual RefPtr VisitReturnStatement(ReturnStatementSyntaxNode* stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitVarDeclrStatement(VarDeclrStatementSyntaxNode* stmt) - { - stmt->decl = stmt->decl->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitWhileStatement(WhileStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitExpressionStatement(ExpressionStatementSyntaxNode* stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As(); - return stmt; - } + virtual RefPtr VisitDoWhileStatement(DoWhileStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitEmptyStatement(EmptyStatementSyntaxNode* stmt) + { + return stmt; + } + virtual RefPtr VisitForStatement(ForStatementSyntaxNode* stmt) + { + if (stmt->InitialStatement) + stmt->InitialStatement = stmt->InitialStatement->Accept(this).As(); + if (stmt->PredicateExpression) + stmt->PredicateExpression = stmt->PredicateExpression->Accept(this).As(); + if (stmt->SideEffectExpression) + stmt->SideEffectExpression = stmt->SideEffectExpression->Accept(this).As(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitIfStatement(IfStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As(); + if (stmt->PositiveStatement) + stmt->PositiveStatement = stmt->PositiveStatement->Accept(this).As(); + if (stmt->NegativeStatement) + stmt->NegativeStatement = stmt->NegativeStatement->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitSwitchStmt(SwitchStmt* stmt) + { + if (stmt->condition) + stmt->condition = stmt->condition->Accept(this).As(); + if (stmt->body) + stmt->body = stmt->body->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitCaseStmt(CaseStmt* stmt) + { + if (stmt->expr) + stmt->expr = stmt->expr->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitDefaultStmt(DefaultStmt* stmt) + { + return stmt; + } + virtual RefPtr VisitReturnStatement(ReturnStatementSyntaxNode* stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitVarDeclrStatement(VarDeclrStatementSyntaxNode* stmt) + { + stmt->decl = stmt->decl->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitWhileStatement(WhileStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitExpressionStatement(ExpressionStatementSyntaxNode* stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As(); + return stmt; + } - virtual RefPtr VisitOperatorExpression(OperatorExpressionSyntaxNode* expr) - { - for (auto && child : expr->Arguments) - child->Accept(this); - return expr; - } - virtual RefPtr VisitConstantExpression(ConstantExpressionSyntaxNode* expr) - { - return expr; - } - virtual RefPtr VisitIndexExpression(IndexExpressionSyntaxNode* expr) - { - if (expr->BaseExpression) - expr->BaseExpression = expr->BaseExpression->Accept(this).As(); - if (expr->IndexExpression) - expr->IndexExpression = expr->IndexExpression->Accept(this).As(); - return expr; - } - virtual RefPtr VisitMemberExpression(MemberExpressionSyntaxNode * stmt) - { - if (stmt->BaseExpression) - stmt->BaseExpression = stmt->BaseExpression->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitSwizzleExpression(SwizzleExpr * expr) - { - if (expr->base) - expr->base->Accept(this); - return expr; - } - virtual RefPtr VisitInvokeExpression(InvokeExpressionSyntaxNode* stmt) - { - stmt->FunctionExpr->Accept(this); - for (auto & arg : stmt->Arguments) - arg = arg->Accept(this).As(); - return stmt; - } - virtual RefPtr VisitTypeCastExpression(TypeCastExpressionSyntaxNode * stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As(); - return stmt->Expression; - } - virtual RefPtr VisitVarExpression(VarExpressionSyntaxNode* expr) - { - return expr; - } + virtual RefPtr VisitOperatorExpression(OperatorExpressionSyntaxNode* expr) + { + for (auto && child : expr->Arguments) + child->Accept(this); + return expr; + } + virtual RefPtr VisitConstantExpression(ConstantExpressionSyntaxNode* expr) + { + return expr; + } + virtual RefPtr VisitIndexExpression(IndexExpressionSyntaxNode* expr) + { + if (expr->BaseExpression) + expr->BaseExpression = expr->BaseExpression->Accept(this).As(); + if (expr->IndexExpression) + expr->IndexExpression = expr->IndexExpression->Accept(this).As(); + return expr; + } + virtual RefPtr VisitMemberExpression(MemberExpressionSyntaxNode * stmt) + { + if (stmt->BaseExpression) + stmt->BaseExpression = stmt->BaseExpression->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitSwizzleExpression(SwizzleExpr * expr) + { + if (expr->base) + expr->base->Accept(this); + return expr; + } + virtual RefPtr VisitInvokeExpression(InvokeExpressionSyntaxNode* stmt) + { + stmt->FunctionExpr->Accept(this); + for (auto & arg : stmt->Arguments) + arg = arg->Accept(this).As(); + return stmt; + } + virtual RefPtr VisitTypeCastExpression(TypeCastExpressionSyntaxNode * stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As(); + return stmt->Expression; + } + virtual RefPtr VisitVarExpression(VarExpressionSyntaxNode* expr) + { + return expr; + } - virtual RefPtr VisitParameter(ParameterSyntaxNode* param) - { - return param; - } - virtual RefPtr VisitGenericApp(GenericAppExpr* type) - { - return type; - } + virtual RefPtr VisitParameter(ParameterSyntaxNode* param) + { + return param; + } + virtual RefPtr VisitGenericApp(GenericAppExpr* type) + { + return type; + } - virtual RefPtr VisitDeclrVariable(Variable* dclr) - { - if (dclr->Expr) - dclr->Expr = dclr->Expr->Accept(this).As(); - return dclr; - } + virtual RefPtr VisitDeclrVariable(Variable* dclr) + { + if (dclr->Expr) + dclr->Expr = dclr->Expr->Accept(this).As(); + return dclr; + } - virtual TypeExp VisitTypeExp(TypeExp const& typeExp) + virtual TypeExp VisitTypeExp(TypeExp const& typeExp) + { + TypeExp result = typeExp; + result.exp = typeExp.exp->Accept(this).As(); + if (auto typeType = result.exp->Type.type.As()) { - TypeExp result = typeExp; - result.exp = typeExp.exp->Accept(this).As(); - if (auto typeType = result.exp->Type.type.As()) - { - result.type = typeType->type; - } - return result; + result.type = typeType->type; } + return result; + } - virtual void VisitExtensionDecl(ExtensionDecl* /*decl*/) - {} + virtual void VisitExtensionDecl(ExtensionDecl* /*decl*/) + {} - virtual void VisitConstructorDecl(ConstructorDecl* /*decl*/) - {} + virtual void VisitConstructorDecl(ConstructorDecl* /*decl*/) + {} - virtual void visitSubscriptDecl(SubscriptDecl* decl) = 0; + virtual void visitSubscriptDecl(SubscriptDecl* decl) = 0; - virtual void visitAccessorDecl(AccessorDecl* decl) = 0; + virtual void visitAccessorDecl(AccessorDecl* decl) = 0; - virtual void visitInterfaceDecl(InterfaceDecl* /*decl*/) = 0; + virtual void visitInterfaceDecl(InterfaceDecl* /*decl*/) = 0; - virtual void visitInheritanceDecl(InheritanceDecl* /*decl*/) = 0; + virtual void visitInheritanceDecl(InheritanceDecl* /*decl*/) = 0; - virtual RefPtr VisitSharedTypeExpr(SharedTypeExpr* typeExpr) - { - return typeExpr; - } + virtual RefPtr VisitSharedTypeExpr(SharedTypeExpr* typeExpr) + { + return typeExpr; + } - virtual void VisitDeclGroup(DeclGroup* declGroup) + virtual void VisitDeclGroup(DeclGroup* declGroup) + { + for (auto decl : declGroup->decls) { - for (auto decl : declGroup->decls) - { - decl->Accept(this); - } + decl->Accept(this); } + } - virtual RefPtr visitInitializerListExpr(InitializerListExpr* expr) = 0; - }; - - // Note(tfoley): These logically belong to `ExpressionType`, - // but order-of-declaration stuff makes that tricky - // - // TODO(tfoley): These should really belong to the compilation context! - // - void RegisterBuiltinDecl( - RefPtr decl, - RefPtr modifier); - void RegisterMagicDecl( - RefPtr decl, - RefPtr modifier); - - // Look up a magic declaration by its name - RefPtr findMagicDecl( - String const& name); - - // Create an instance of a syntax class by name - SyntaxNodeBase* createInstanceOfSyntaxClassByName( - String const& name); - - } -} + virtual RefPtr visitInitializerListExpr(InitializerListExpr* expr) = 0; + }; + + // Note(tfoley): These logically belong to `ExpressionType`, + // but order-of-declaration stuff makes that tricky + // + // TODO(tfoley): These should really belong to the compilation context! + // + void RegisterBuiltinDecl( + RefPtr decl, + RefPtr modifier); + void RegisterMagicDecl( + RefPtr decl, + RefPtr modifier); + + // Look up a magic declaration by its name + RefPtr findMagicDecl( + String const& name); + + // Create an instance of a syntax class by name + SyntaxNodeBase* createInstanceOfSyntaxClassByName( + String const& name); + +} // namespace Slang #endif \ No newline at end of file -- cgit v1.2.3