diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-15 13:12:51 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-15 13:12:51 -0700 |
| commit | 517513645afb8eaf4841e7b7035f1ba3a9c7cd57 (patch) | |
| tree | eb0fdf58f5f42c427ade3aac136a9053fbf21d54 /source/slang/syntax.h | |
| parent | c34a433d7aa3fdbfefee22f20d5aac2d960f392a (diff) | |
Rename `Slang::Compiler` -> `Slang`
This gets rid of one unecessary namespace.
Diffstat (limited to 'source/slang/syntax.h')
| -rw-r--r-- | source/slang/syntax.h | 4573 |
1 files changed, 2285 insertions, 2288 deletions
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<Modifier> 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<Modifier> 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); + 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 - { - }; - - // 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<typename T> + 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<typename T> - 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<T*>(m)) return m; - m = m->next.Ptr(); - } + if (!m) return m; + if (dynamic_cast<T*>(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<Modifier> first; + Modifier* modifiers; + }; - template<typename T> - FilteredModifierList<T> getModifiersOfType() { return FilteredModifierList<T>(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<Modifier> first; - // Find the first modifier of a given type, or return `nullptr` if none is found. - template<typename T> - T* findModifier() - { - return *getModifiersOfType<T>().begin(); - } + template<typename T> + FilteredModifierList<T> getModifiersOfType() { return FilteredModifierList<T>(first.Ptr()); } - template<typename T> - bool hasModifier() { return findModifier<T>() != nullptr; } + // Find the first modifier of a given type, or return `nullptr` if none is found. + template<typename T> + T* findModifier() + { + return *getModifiersOfType<T>().begin(); + } - FilteredModifierList<Modifier>::Iterator begin() { return FilteredModifierList<Modifier>::Iterator(first.Ptr()); } - FilteredModifierList<Modifier>::Iterator end() { return FilteredModifierList<Modifier>::Iterator(nullptr); } - }; + template<typename T> + bool hasModifier() { return findModifier<T>() != nullptr; } + FilteredModifierList<Modifier>::Iterator begin() { return FilteredModifierList<Modifier>::Iterator(first.Ptr()); } + FilteredModifierList<Modifier>::Iterator end() { return FilteredModifierList<Modifier>::Iterator(nullptr); } + }; - 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<Val> 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<Val> 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<Val*>(&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<Val> 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<Val> 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<Val*>(&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<IntVal> 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<IntVal> val); - // Trivial case of a value that is just a constant integer - class ConstantIntVal : public IntVal - { - public: - int value; + // 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<ExpressionType> Error; + static RefPtr<ExpressionType> initializerListType; + static RefPtr<ExpressionType> Overloaded; - ConstantIntVal(int value) - : value(value) - {} + static Dictionary<int, RefPtr<ExpressionType>> sBuiltinTypes; + static Dictionary<String, Decl*> sMagicDecls; - virtual bool EqualsVal(Val* val) override; - virtual String ToString() override; - virtual int GetHashCode() override; - }; + // Note: just exists to make sure we can clean up + // canonical types we create along the way + static List<RefPtr<ExpressionType>> sCanonicalTypes; - // 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<ExpressionType> Error; - static RefPtr<ExpressionType> initializerListType; - static RefPtr<ExpressionType> Overloaded; - static Dictionary<int, RefPtr<ExpressionType>> sBuiltinTypes; - static Dictionary<String, Decl*> sMagicDecls; + static ExpressionType* GetBool(); + static ExpressionType* GetFloat(); + static ExpressionType* GetInt(); + static ExpressionType* GetUInt(); + static ExpressionType* GetVoid(); + static ExpressionType* getInitializerListType(); + static ExpressionType* GetError(); - // Note: just exists to make sure we can clean up - // canonical types we create along the way - static List<RefPtr<ExpressionType>> sCanonicalTypes; + public: + virtual String ToString() = 0; + bool Equals(ExpressionType * type); + bool Equals(RefPtr<ExpressionType> type); + bool IsVectorType() { return As<VectorExpressionType>() != nullptr; } + bool IsArray() { return As<ArrayExpressionType>() != nullptr; } - static ExpressionType* GetBool(); - static ExpressionType* GetFloat(); - static ExpressionType* GetInt(); - static ExpressionType* GetUInt(); - static ExpressionType* GetVoid(); - static ExpressionType* getInitializerListType(); - static ExpressionType* GetError(); + template<typename T> + T* As() + { + return dynamic_cast<T*>(GetCanonicalType()); + } - public: - virtual String ToString() = 0; + // Convenience/legacy wrappers for `As<>` + ArithmeticExpressionType * AsArithmeticType() { return As<ArithmeticExpressionType>(); } + BasicExpressionType * AsBasicType() { return As<BasicExpressionType>(); } + VectorExpressionType * AsVectorType() { return As<VectorExpressionType>(); } + MatrixExpressionType * AsMatrixType() { return As<MatrixExpressionType>(); } + ArrayExpressionType * AsArrayType() { return As<ArrayExpressionType>(); } - bool Equals(ExpressionType * type); - bool Equals(RefPtr<ExpressionType> type); + DeclRefType* AsDeclRefType() { return As<DeclRefType>(); } - bool IsVectorType() { return As<VectorExpressionType>() != nullptr; } - bool IsArray() { return As<ArrayExpressionType>() != nullptr; } + NamedExpressionType* AsNamedType(); - template<typename T> - T* As() - { - return dynamic_cast<T*>(GetCanonicalType()); - } + bool IsTextureOrSampler(); + bool IsTexture() { return As<TextureType>() != nullptr; } + bool IsSampler() { return As<SamplerStateType>() != nullptr; } + bool IsStruct(); + bool IsClass(); + static void Init(); + static void Finalize(); + ExpressionType* GetCanonicalType(); - // Convenience/legacy wrappers for `As<>` - ArithmeticExpressionType * AsArithmeticType() { return As<ArithmeticExpressionType>(); } - BasicExpressionType * AsBasicType() { return As<BasicExpressionType>(); } - VectorExpressionType * AsVectorType() { return As<VectorExpressionType>(); } - MatrixExpressionType * AsMatrixType() { return As<MatrixExpressionType>(); } - ArrayExpressionType * AsArrayType() { return As<ArrayExpressionType>(); } + virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; - DeclRefType* AsDeclRefType() { return As<DeclRefType>(); } + virtual bool EqualsVal(Val* val) override; + protected: + virtual bool EqualsImpl(ExpressionType * type) = 0; - NamedExpressionType* AsNamedType(); + virtual ExpressionType* CreateCanonicalType() = 0; + ExpressionType* canonicalType = nullptr; + }; - bool IsTextureOrSampler(); - bool IsTexture() { return As<TextureType>() != nullptr; } - bool IsSampler() { return As<SamplerStateType>() != nullptr; } - bool IsStruct(); - bool IsClass(); - static void Init(); - static void Finalize(); - ExpressionType* GetCanonicalType(); + // 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; - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + // The actual values of the arguments + List<RefPtr<Val>> args; - virtual bool EqualsVal(Val* val) override; - protected: - virtual bool EqualsImpl(ExpressionType * type) = 0; + // Any further substitutions, relating to outer generic declarations + RefPtr<Substitutions> outer; - virtual ExpressionType* CreateCanonicalType() = 0; - ExpressionType* canonicalType = nullptr; - }; + // Apply a set of substitutions to the bindings in this substitution + RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff); - // A substitution represents a binding of certain - // type-level variables to concrete argument values - class Substitutions : public RefObject + // Check if these are equivalent substitutiosn to another set + bool Equals(Substitutions* subst); + bool operator == (const Substitutions & subst) { - public: - // The generic declaration that defines the - // parametesr we are binding to arguments - GenericDecl* genericDecl; - - // The actual values of the arguments - List<RefPtr<Val>> args; - - // Any further substitutions, relating to outer generic declarations - RefPtr<Substitutions> outer; - - // Apply a set of substitutions to the bindings in this substitution - RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff); - - // Check if these are equivalent substitutiosn to another set - bool Equals(Substitutions* subst); - bool operator == (const Substitutions & subst) - { - return Equals(const_cast<Substitutions*>(&subst)); - } - int GetHashCode() const + return Equals(const_cast<Substitutions*>(&subst)); + } + int GetHashCode() const + { + int rs = 0; + for (auto && v : args) { - int rs = 0; - for (auto && v : args) - { - rs ^= v->GetHashCode(); - rs *= 16777619; - } - return rs; + rs ^= v->GetHashCode(); + rs *= 16777619; } - }; - - class SyntaxNode : public SyntaxNodeBase - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) = 0; - }; - - class ContainerDecl; - class SpecializeModifier; - - // Represents how much checking has been applied to a declaration. - enum class DeclCheckState : uint8_t - { - // The declaration has been parsed, but not checked - Unchecked, - - // We are in the process of checking the declaration "header" - // (those parts of the declaration needed in order to - // reference it) - CheckingHeader, + return rs; + } + }; - // We are done checking the declaration header. - CheckedHeader, + class SyntaxNode : public SyntaxNodeBase + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) = 0; + }; - // We have checked the declaration fully. - Checked, - }; + class ContainerDecl; + class SpecializeModifier; - // A syntax node which can have modifiers appled - class ModifiableSyntaxNode : public SyntaxNode - { - public: - Modifiers modifiers; + // Represents how much checking has been applied to a declaration. + enum class DeclCheckState : uint8_t + { + // The declaration has been parsed, but not checked + Unchecked, - template<typename T> - FilteredModifierList<T> GetModifiersOfType() { return FilteredModifierList<T>(modifiers.first.Ptr()); } + // We are in the process of checking the declaration "header" + // (those parts of the declaration needed in order to + // reference it) + CheckingHeader, - // Find the first modifier of a given type, or return `nullptr` if none is found. - template<typename T> - T* FindModifier() - { - return *GetModifiersOfType<T>().begin(); - } + // We are done checking the declaration header. + CheckedHeader, - template<typename T> - bool HasModifier() { return FindModifier<T>() != nullptr; } - }; + // We have checked the declaration fully. + Checked, + }; - void addModifier( - RefPtr<ModifiableSyntaxNode> syntax, - RefPtr<Modifier> modifier); + // A syntax node which can have modifiers appled + class ModifiableSyntaxNode : public SyntaxNode + { + public: + Modifiers modifiers; + template<typename T> + FilteredModifierList<T> GetModifiersOfType() { return FilteredModifierList<T>(modifiers.first.Ptr()); } - // An intermediate type to represent either a single declaration, or a group of declarations - class DeclBase : public ModifiableSyntaxNode + // Find the first modifier of a given type, or return `nullptr` if none is found. + template<typename T> + T* FindModifier() { - public: - }; + return *GetModifiersOfType<T>().begin(); + } - class Decl : public DeclBase - { - public: - ContainerDecl* ParentDecl; + template<typename T> + bool HasModifier() { return FindModifier<T>() != nullptr; } + }; - Token Name; - String const& getName() { return Name.Content; } - Token const& getNameToken() { return Name; } + void addModifier( + RefPtr<ModifiableSyntaxNode> syntax, + RefPtr<Modifier> modifier); - DeclCheckState checkState = DeclCheckState::Unchecked; + // An intermediate type to represent either a single declaration, or a group of declarations + class DeclBase : public ModifiableSyntaxNode + { + public: + }; - // The next declaration defined in the same container with the same name - Decl* nextInContainerWithSameName = nullptr; + class Decl : public DeclBase + { + public: + ContainerDecl* ParentDecl; - bool IsChecked(DeclCheckState state) { return checkState >= state; } - void SetCheckState(DeclCheckState state) - { - assert(state >= checkState); - checkState = state; - } - }; + Token Name; + String const& getName() { return Name.Content; } + Token const& getNameToken() { return Name; } - struct QualType - { - RefPtr<ExpressionType> type; - bool IsLeftValue; - QualType() - : IsLeftValue(false) - {} + DeclCheckState checkState = DeclCheckState::Unchecked; - QualType(RefPtr<ExpressionType> type) - : type(type) - , IsLeftValue(false) - {} + // The next declaration defined in the same container with the same name + Decl* nextInContainerWithSameName = nullptr; - QualType(ExpressionType* type) - : type(type) - , IsLeftValue(false) - {} + bool IsChecked(DeclCheckState state) { return checkState >= state; } + void SetCheckState(DeclCheckState state) + { + assert(state >= checkState); + checkState = state; + } + }; - void operator=(RefPtr<ExpressionType> t) - { - *this = QualType(t); - } + struct QualType + { + RefPtr<ExpressionType> type; + bool IsLeftValue; - void operator=(ExpressionType* t) - { - *this = QualType(t); - } + QualType() + : IsLeftValue(false) + {} - ExpressionType* Ptr() { return type.Ptr(); } + QualType(RefPtr<ExpressionType> type) + : type(type) + , IsLeftValue(false) + {} - operator RefPtr<ExpressionType>() { return type; } - RefPtr<ExpressionType> operator->() { return type; } - }; + QualType(ExpressionType* type) + : type(type) + , IsLeftValue(false) + {} - class ExpressionSyntaxNode : public SyntaxNode + void operator=(RefPtr<ExpressionType> t) { - public: - QualType Type; - ExpressionSyntaxNode() - {} - }; - - - + *this = QualType(t); + } - // A reference to a declaration, which may include - // substitutions for generic parameters. - struct DeclRef + void operator=(ExpressionType* t) { - typedef Decl DeclType; - - // The underlying declaration - Decl* decl = nullptr; - Decl* GetDecl() const { return decl; } + *this = QualType(t); + } - // Optionally, a chain of substititions to perform - RefPtr<Substitutions> substitutions; + ExpressionType* Ptr() { return type.Ptr(); } - DeclRef() - {} + operator RefPtr<ExpressionType>() { return type; } + RefPtr<ExpressionType> operator->() { return type; } + }; - DeclRef(Decl* decl, RefPtr<Substitutions> substitutions) - : decl(decl) - , substitutions(substitutions) - {} + class ExpressionSyntaxNode : public SyntaxNode + { + public: + QualType Type; + ExpressionSyntaxNode() + {} + }; - // Apply substitutions to a type or ddeclaration - RefPtr<ExpressionType> Substitute(RefPtr<ExpressionType> type) const; - DeclRef Substitute(DeclRef declRef) const; - // Apply substitutions to an expression - RefPtr<ExpressionSyntaxNode> Substitute(RefPtr<ExpressionSyntaxNode> expr) const; - // 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); - } + // A reference to a declaration, which may include + // substitutions for generic parameters. + struct DeclRef + { + typedef Decl DeclType; - // Convenience accessors for common properties of declarations - String const& GetName() const; - DeclRef GetParent() const; + // The underlying declaration + Decl* decl = nullptr; + Decl* GetDecl() const { return decl; } - // "dynamic cast" to a more specific declaration reference type - template<typename T> - T As() const - { - T result; - result.decl = dynamic_cast<T::DeclType*>(decl); - result.substitutions = substitutions; - return result; - } + // Optionally, a chain of substititions to perform + RefPtr<Substitutions> substitutions; - // Implicit conversion mostly so we can use a `DeclRef` - // in a conditional context - operator Decl*() const - { - return decl; - } + DeclRef() + {} - int GetHashCode() const; - }; + DeclRef(Decl* decl, RefPtr<Substitutions> substitutions) + : decl(decl) + , substitutions(substitutions) + {} - // Helper macro for defining `DeclRef` subtypes - #define SLANG_DECLARE_DECL_REF(D) \ - typedef D DeclType; \ - D* GetDecl() const { return (D*) decl; } \ - /* */ + // Apply substitutions to a type or ddeclaration + RefPtr<ExpressionType> Substitute(RefPtr<ExpressionType> type) const; + DeclRef Substitute(DeclRef declRef) const; + // Apply substitutions to an expression + RefPtr<ExpressionSyntaxNode> Substitute(RefPtr<ExpressionSyntaxNode> expr) const; + // Apply substitutions to this declaration reference + DeclRef SubstituteImpl(Substitutions* subst, int* ioDiff); - // The type of a reference to an overloaded name - class OverloadGroupType : public ExpressionType + // Check if this is an equivalent declaration reference to another + bool Equals(DeclRef const& declRef) const; + bool operator == (const DeclRef& other) const { - public: - virtual String ToString() override; + 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; - // The type of an initializer-list expression (before it has - // been coerced to some other type) - class InitializerListType : public ExpressionType + // "dynamic cast" to a more specific declaration reference type + template<typename T> + T As() const { - public: - virtual String ToString() override; - - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + T result; + result.decl = dynamic_cast<T::DeclType*>(decl); + result.substitutions = substitutions; + return result; + } - // The type of an expression that was erroneous - class ErrorType : public ExpressionType + // Implicit conversion mostly so we can use a `DeclRef` + // in a conditional context + operator Decl*() const { - public: - virtual String ToString() override; - - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + return decl; + } - // A type that takes the form of a reference to some declaration - class DeclRefType : public ExpressionType - { - public: - DeclRef declRef; + int GetHashCode() const; + }; - virtual String ToString() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + // Helper macro for defining `DeclRef` subtypes + #define SLANG_DECLARE_DECL_REF(D) \ + typedef D DeclType; \ + D* GetDecl() const { return (D*) decl; } \ + /* */ - 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; - }; + // 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; - class FunctionDeclBase; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - class BasicExpressionType : public ArithmeticExpressionType - { - public: - BaseType BaseType; + // The type of an expression that was erroneous + class ErrorType : public ExpressionType + { + public: + virtual String ToString() override; - 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; - }; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; + // 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<Val> 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; + }; - class TextureTypeBase : public DeclRefType - { - public: - // The type that results from fetching an element from this texture - RefPtr<ExpressionType> elementType; + class FunctionDeclBase; - // Bits representing the kind of texture type we are looking at - // (e.g., `Texture2DMS` vs. `TextureCubeArray`) - typedef uint16_t Flavor; - Flavor flavor; + class BasicExpressionType : public ArithmeticExpressionType + { + public: + BaseType BaseType; - enum - { - // Mask for the overall "shape" of the texture - ShapeMask = SLANG_RESOURCE_BASE_SHAPE_MASK, + 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; + }; - // Flag for whether the shape has "array-ness" - ArrayFlag = SLANG_TEXTURE_ARRAY_FLAG, - // Whether or not the texture stores multiple samples per pixel - MultisampleFlag = SLANG_TEXTURE_MULTISAMPLE_FLAG, + class TextureTypeBase : public DeclRefType + { + public: + // The type that results from fetching an element from this texture + RefPtr<ExpressionType> elementType; - // Whether or not this is a shadow texture - // - // TODO(tfoley): is this even meaningful/used? - // ShadowFlag = 0x80, - }; + // Bits representing the kind of texture type we are looking at + // (e.g., `Texture2DMS` vs. `TextureCubeArray`) + typedef uint16_t Flavor; + Flavor flavor; - 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, - }; - + enum + { + // Mask for the overall "shape" of the texture + ShapeMask = SLANG_RESOURCE_BASE_SHAPE_MASK, - 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; } + // Flag for whether the shape has "array-ness" + ArrayFlag = SLANG_TEXTURE_ARRAY_FLAG, - SlangResourceShape getShape() const { return flavor & 0xFF; } - SlangResourceAccess getAccess() const { return (flavor >> 8) & 0xFF; } + // Whether or not the texture stores multiple samples per pixel + MultisampleFlag = SLANG_TEXTURE_MULTISAMPLE_FLAG, - TextureTypeBase( - Flavor flavor, - RefPtr<ExpressionType> elementType) - : elementType(elementType) - , flavor(flavor) - {} + // Whether or not this is a shadow texture + // + // TODO(tfoley): is this even meaningful/used? + // ShadowFlag = 0x80, }; - class TextureType : public TextureTypeBase + enum Shape : uint8_t { - public: - TextureType( - Flavor flavor, - RefPtr<ExpressionType> elementType) - : TextureTypeBase(flavor, elementType) - {} - }; + Shape1D = SLANG_TEXTURE_1D, + Shape2D = SLANG_TEXTURE_2D, + Shape3D = SLANG_TEXTURE_3D, + ShapeCube = SLANG_TEXTURE_CUBE, - // 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<ExpressionType> elementType) - : TextureTypeBase(flavor, elementType) - {} + Shape1DArray = Shape1D | ArrayFlag, + Shape2DArray = Shape2D | ArrayFlag, + // No Shape3DArray + ShapeCubeArray = ShapeCube | ArrayFlag, }; + - // This is a base type for `image*` types, as they exist in GLSL - class GLSLImageType : public TextureTypeBase - { - public: - GLSLImageType( - Flavor flavor, - RefPtr<ExpressionType> elementType) - : TextureTypeBase(flavor, elementType) - {} - }; + 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; } - class SamplerStateType : public DeclRefType - { - public: - // What flavor of sampler state is this - enum class Flavor : uint8_t - { - SamplerState, - SamplerComparisonState, - }; - Flavor flavor; - }; + SlangResourceShape getShape() const { return flavor & 0xFF; } + SlangResourceAccess getAccess() const { return (flavor >> 8) & 0xFF; } + + TextureTypeBase( + Flavor flavor, + RefPtr<ExpressionType> elementType) + : elementType(elementType) + , flavor(flavor) + {} + }; - // Other cases of generic types known to the compiler - class BuiltinGenericType : public DeclRefType + class TextureType : public TextureTypeBase + { + public: + TextureType( + Flavor flavor, + RefPtr<ExpressionType> 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<ExpressionType> 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<ExpressionType> elementType) + : TextureTypeBase(flavor, elementType) + {} + }; + + class SamplerStateType : public DeclRefType + { + public: + // What flavor of sampler state is this + enum class Flavor : uint8_t { - public: - RefPtr<ExpressionType> elementType; + SamplerState, + SamplerComparisonState, }; + Flavor flavor; + }; - // Types that behave like pointers, in that they can be - // dereferenced (implicitly) to access members defined - // in the element type. - class PointerLikeType : public BuiltinGenericType - {}; + // Other cases of generic types known to the compiler + class BuiltinGenericType : public DeclRefType + { + public: + RefPtr<ExpressionType> elementType; + }; - // 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 {}; + // Types that behave like pointers, in that they can be + // dereferenced (implicitly) to access members defined + // in the element type. + class PointerLikeType : public BuiltinGenericType + {}; - // HLSL buffer-type resources + // 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 HLSLBufferType : public BuiltinGenericType {}; - class HLSLRWBufferType : public BuiltinGenericType {}; - class HLSLStructuredBufferType : public BuiltinGenericType {}; - class HLSLRWStructuredBufferType : public BuiltinGenericType {}; + // HLSL buffer-type resources - class UntypedBufferResourceType : public DeclRefType {}; - class HLSLByteAddressBufferType : public UntypedBufferResourceType {}; - class HLSLRWByteAddressBufferType : public UntypedBufferResourceType {}; + class HLSLBufferType : public BuiltinGenericType {}; + class HLSLRWBufferType : public BuiltinGenericType {}; + class HLSLStructuredBufferType : public BuiltinGenericType {}; + class HLSLRWStructuredBufferType : public BuiltinGenericType {}; - class HLSLAppendStructuredBufferType : public BuiltinGenericType {}; - class HLSLConsumeStructuredBufferType : public BuiltinGenericType {}; + class UntypedBufferResourceType : public DeclRefType {}; + class HLSLByteAddressBufferType : public UntypedBufferResourceType {}; + class HLSLRWByteAddressBufferType : public UntypedBufferResourceType {}; - class HLSLInputPatchType : public BuiltinGenericType {}; - class HLSLOutputPatchType : public BuiltinGenericType {}; + class HLSLAppendStructuredBufferType : public BuiltinGenericType {}; + class HLSLConsumeStructuredBufferType : public BuiltinGenericType {}; - // HLSL geometry shader output stream types + class HLSLInputPatchType : public BuiltinGenericType {}; + class HLSLOutputPatchType : public BuiltinGenericType {}; - class HLSLStreamOutputType : public BuiltinGenericType {}; - class HLSLPointStreamType : public HLSLStreamOutputType {}; - class HLSLLineStreamType : public HLSLStreamOutputType {}; - class HLSLTriangleStreamType : public HLSLStreamOutputType {}; + // HLSL geometry shader output stream types - // - class GLSLInputAttachmentType : public DeclRefType {}; + class HLSLStreamOutputType : public BuiltinGenericType {}; + class HLSLPointStreamType : public HLSLStreamOutputType {}; + class HLSLLineStreamType : public HLSLStreamOutputType {}; + class HLSLTriangleStreamType : public HLSLStreamOutputType {}; - // Base class for types used when desugaring parameter block - // declarations, includeing HLSL `cbuffer` or GLSL `uniform` blocks. - class ParameterBlockType : public PointerLikeType {}; + // + class GLSLInputAttachmentType : public DeclRefType {}; - class UniformParameterBlockType : public ParameterBlockType {}; - class VaryingParameterBlockType : public ParameterBlockType {}; + // Base class for types used when desugaring parameter block + // declarations, includeing HLSL `cbuffer` or GLSL `uniform` blocks. + class ParameterBlockType : public PointerLikeType {}; - // Type for HLSL `cbuffer` declarations, and `ConstantBuffer<T>` - // ALso used for GLSL `uniform` blocks. - class ConstantBufferType : public UniformParameterBlockType {}; + class UniformParameterBlockType : public ParameterBlockType {}; + class VaryingParameterBlockType : public ParameterBlockType {}; - // Type for HLSL `tbuffer` declarations, and `TextureBuffer<T>` - class TextureBufferType : public UniformParameterBlockType {}; + // Type for HLSL `cbuffer` declarations, and `ConstantBuffer<T>` + // ALso used for GLSL `uniform` blocks. + class ConstantBufferType : public UniformParameterBlockType {}; - // Type for GLSL `in` and `out` blocks - class GLSLInputParameterBlockType : public VaryingParameterBlockType {}; - class GLSLOutputParameterBlockType : public VaryingParameterBlockType {}; + // Type for HLSL `tbuffer` declarations, and `TextureBuffer<T>` + class TextureBufferType : public UniformParameterBlockType {}; - // Type for GLLSL `buffer` blocks - class GLSLShaderStorageBufferType : public UniformParameterBlockType {}; + // Type for GLSL `in` and `out` blocks + class GLSLInputParameterBlockType : public VaryingParameterBlockType {}; + class GLSLOutputParameterBlockType : public VaryingParameterBlockType {}; - class ArrayExpressionType : public ExpressionType - { - public: - RefPtr<ExpressionType> BaseType; - RefPtr<IntVal> ArrayLength; - virtual CoreLib::Basic::String ToString() override; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + // Type for GLLSL `buffer` blocks + class GLSLShaderStorageBufferType : public UniformParameterBlockType {}; - // 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<ExpressionType> type) - : type(type) - {} + class ArrayExpressionType : public ExpressionType + { + public: + RefPtr<ExpressionType> BaseType; + RefPtr<IntVal> 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<ExpressionType> type) + : type(type) + {} - // The type that this is the type of... - RefPtr<ExpressionType> type; + // The type that this is the type of... + RefPtr<ExpressionType> type; - 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 GenericDecl; + class GenericDecl; - // A vector type, e.g., `vector<T,N>` - class VectorExpressionType : public ArithmeticExpressionType - { - public: + // A vector type, e.g., `vector<T,N>` + class VectorExpressionType : public ArithmeticExpressionType + { + public: #if 0 - VectorExpressionType( - RefPtr<ExpressionType> elementType, - RefPtr<IntVal> elementCount) - : elementType(elementType) - , elementCount(elementCount) - {} + VectorExpressionType( + RefPtr<ExpressionType> elementType, + RefPtr<IntVal> elementCount) + : elementType(elementType) + , elementCount(elementCount) + {} #endif - // The type of vector elements. - // As an invariant, this should be a basic type or an alias. - RefPtr<ExpressionType> elementType; + // The type of vector elements. + // As an invariant, this should be a basic type or an alias. + RefPtr<ExpressionType> elementType; - // The number of elements - RefPtr<IntVal> elementCount; + // The number of elements + RefPtr<IntVal> elementCount; - virtual String ToString() override; + virtual String ToString() override; - protected: - virtual BasicExpressionType* GetScalarType() override; - }; + protected: + virtual BasicExpressionType* GetScalarType() override; + }; - // A matrix type, e.g., `matrix<T,R,C>` - 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` + // A matrix type, e.g., `matrix<T,R,C>` + 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<ExpressionType> elementType; + // The type of vector elements. + // As an invariant, this should be a basic type or an alias. + RefPtr<ExpressionType> elementType; - // The type of the matrix rows - RefPtr<VectorExpressionType> rowType; + // The type of the matrix rows + RefPtr<VectorExpressionType> rowType; - // The number of rows and columns - RefPtr<IntVal> rowCount; - RefPtr<IntVal> colCount; + // The number of rows and columns + RefPtr<IntVal> rowCount; + RefPtr<IntVal> colCount; #endif - ExpressionType* getElementType(); - IntVal* getRowCount(); - IntVal* getColumnCount(); + ExpressionType* getElementType(); + IntVal* getRowCount(); + IntVal* getColumnCount(); - virtual String ToString() override; + virtual String ToString() override; - protected: - virtual BasicExpressionType* GetScalarType() override; - }; + protected: + virtual BasicExpressionType* GetScalarType() override; + }; - inline BaseType GetVectorBaseType(VectorExpressionType* vecType) { - return vecType->elementType->AsBasicType()->BaseType; - } + inline BaseType GetVectorBaseType(VectorExpressionType* vecType) { + return vecType->elementType->AsBasicType()->BaseType; + } - inline int GetVectorSize(VectorExpressionType* vecType) - { - auto constantVal = vecType->elementCount.As<ConstantIntVal>(); - if (constantVal) - return constantVal->value; - // TODO: what to do in this case? - return 0; - } + inline int GetVectorSize(VectorExpressionType* vecType) + { + auto constantVal = vecType->elementCount.As<ConstantIntVal>(); + if (constantVal) + return constantVal->value; + // TODO: what to do in this case? + return 0; + } - class Type - { - public: - RefPtr<ExpressionType> 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<String> ConstrainedWorlds, FeasibleWorlds; - EnumerableHashSet<String> PinnedWorlds; - }; + class Type + { + public: + RefPtr<ExpressionType> 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<String> ConstrainedWorlds, FeasibleWorlds; + EnumerableHashSet<String> PinnedWorlds; + }; - class ContainerDecl; + class ContainerDecl; - // A group of declarations that should be treated as a unit - class DeclGroup : public DeclBase - { - public: - List<RefPtr<Decl>> decls; + // A group of declarations that should be treated as a unit + class DeclGroup : public DeclBase + { + public: + List<RefPtr<Decl>> decls; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - template<typename T> - struct FilteredMemberList - { - typedef RefPtr<Decl> Element; + template<typename T> + struct FilteredMemberList + { + typedef RefPtr<Decl> Element; - FilteredMemberList() - : mBegin(NULL) - , mEnd(NULL) - {} + FilteredMemberList() + : mBegin(NULL) + , mEnd(NULL) + {} - explicit FilteredMemberList( - List<Element> const& list) - : mBegin(Adjust(list.begin(), list.end())) - , mEnd(list.end()) - {} + explicit FilteredMemberList( + List<Element> const& list) + : mBegin(Adjust(list.begin(), list.end())) + , mEnd(list.end()) + {} + + struct Iterator + { + Element* mCursor; + Element* mEnd; - struct Iterator + bool operator!=(Iterator const& other) { - Element* mCursor; - Element* mEnd; - - bool operator!=(Iterator const& other) - { - return mCursor != other.mCursor; - } - - void operator++() - { - mCursor = Adjust(mCursor + 1, mEnd); - } - - RefPtr<T>& operator*() - { - return *(RefPtr<T>*)mCursor; - } - }; + return mCursor != other.mCursor; + } - Iterator begin() + void operator++() { - Iterator iter = { mBegin, mEnd }; - return iter; + mCursor = Adjust(mCursor + 1, mEnd); } - Iterator end() + RefPtr<T>& operator*() { - Iterator iter = { mEnd, mEnd }; - return iter; + return *(RefPtr<T>*)mCursor; } + }; - static Element* Adjust(Element* cursor, Element* end) + Iterator begin() + { + Iterator iter = { mBegin, mEnd }; + return iter; + } + + Iterator end() + { + Iterator iter = { mEnd, mEnd }; + return iter; + } + + static Element* Adjust(Element* cursor, Element* end) + { + while (cursor != end) { - while (cursor != end) - { - if ((*cursor).As<T>()) - return cursor; - cursor++; - } - return cursor; + if ((*cursor).As<T>()) + return cursor; + cursor++; } + return cursor; + } - // TODO(tfoley): It is ugly to have these. - // We should probably fix the call sites instead. - RefPtr<T>& First() { return *begin(); } - int Count() + // TODO(tfoley): It is ugly to have these. + // We should probably fix the call sites instead. + RefPtr<T>& First() { return *begin(); } + int Count() + { + int count = 0; + for (auto iter : (*this)) { - int count = 0; - for (auto iter : (*this)) - { - (void)iter; - count++; - } - return count; + (void)iter; + count++; } + return count; + } - List<RefPtr<T>> ToArray() + List<RefPtr<T>> ToArray() + { + List<RefPtr<T>> result; + for (auto element : (*this)) { - List<RefPtr<T>> result; - for (auto element : (*this)) - { - result.Add(element); - } - return result; + result.Add(element); } + return result; + } - Element* mBegin; - Element* mEnd; - }; + Element* mBegin; + Element* mEnd; + }; - struct TransparentMemberInfo - { - // The declaration of the transparent member - Decl* decl; - }; + struct TransparentMemberInfo + { + // The declaration of the transparent member + Decl* decl; + }; + + // A "container" decl is a parent to other declarations + class ContainerDecl : public Decl + { + public: + List<RefPtr<Decl>> Members; - // A "container" decl is a parent to other declarations - class ContainerDecl : public Decl + template<typename T> + FilteredMemberList<T> GetMembersOfType() { - public: - List<RefPtr<Decl>> Members; + return FilteredMemberList<T>(Members); + } - template<typename T> - FilteredMemberList<T> GetMembersOfType() - { - return FilteredMemberList<T>(Members); - } + // Dictionary for looking up members by name. + // This is built on demand before performing lookup. + Dictionary<String, Decl*> memberDictionary; - // Dictionary for looking up members by name. - // This is built on demand before performing lookup. - Dictionary<String, Decl*> memberDictionary; + // Whether the `memberDictionary` is valid. + // Should be set to `false` if any members get added/remoed. + bool memberDictionaryIsValid = false; - // Whether the `memberDictionary` is valid. - // Should be set to `false` if any members get added/remoed. - bool memberDictionaryIsValid = false; + // A list of transparent members, to be used in lookup + // Note: this is only valid if `memberDictionaryIsValid` is true + List<TransparentMemberInfo> transparentMembers; + }; - // A list of transparent members, to be used in lookup - // Note: this is only valid if `memberDictionaryIsValid` is true - List<TransparentMemberInfo> transparentMembers; - }; + template<typename T> + struct FilteredMemberRefList + { + List<RefPtr<Decl>> const& decls; + RefPtr<Substitutions> substitutions; + + FilteredMemberRefList( + List<RefPtr<Decl>> const& decls, + RefPtr<Substitutions> substitutions) + : decls(decls) + , substitutions(substitutions) + {} + + int Count() const + { + int count = 0; + for (auto d : *this) + count++; + return count; + } - template<typename T> - struct FilteredMemberRefList + List<T> ToArray() const + { + List<T> result; + for (auto d : *this) + result.Add(d); + return result; + } + + struct Iterator { - List<RefPtr<Decl>> const& decls; - RefPtr<Substitutions> substitutions; + FilteredMemberRefList const* list; + RefPtr<Decl>* ptr; + RefPtr<Decl>* end; - FilteredMemberRefList( - List<RefPtr<Decl>> const& decls, - RefPtr<Substitutions> substitutions) - : decls(decls) - , substitutions(substitutions) + Iterator() : list(nullptr), ptr(nullptr) {} + Iterator( + FilteredMemberRefList const* list, + RefPtr<Decl>* ptr, + RefPtr<Decl>* 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<T> ToArray() const + void operator++() { - List<T> result; - for (auto d : *this) - result.Add(d); - return result; + ptr = list->Adjust(ptr + 1, end); } - struct Iterator + T operator*() { - FilteredMemberRefList const* list; - RefPtr<Decl>* ptr; - RefPtr<Decl>* end; - - Iterator() : list(nullptr), ptr(nullptr) {} - Iterator( - FilteredMemberRefList const* list, - RefPtr<Decl>* ptr, - RefPtr<Decl>* end) - : list(list) - , ptr(ptr) - , end(end) - {} - - bool operator!=(Iterator other) - { - return ptr != other.ptr; - } - - void operator++() - { - ptr = list->Adjust(ptr + 1, end); - } - - T operator*() - { - return DeclRef(ptr->Ptr(), list->substitutions).As<T>(); - } - }; - - Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); } - Iterator end() const { return Iterator(this, decls.end(), decls.end()); } - - RefPtr<Decl>* Adjust(RefPtr<Decl>* ptr, RefPtr<Decl>* end) const - { - while (ptr != end) - { - DeclRef declRef(ptr->Ptr(), substitutions); - if (declRef.As<T>()) - return ptr; - ptr++; - } - return end; + return DeclRef(ptr->Ptr(), list->substitutions).As<T>(); } }; - struct ContainerDeclRef : DeclRef - { - SLANG_DECLARE_DECL_REF(ContainerDecl); - - FilteredMemberRefList<DeclRef> GetMembers() const - { - return FilteredMemberRefList<DeclRef>(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<typename T> - FilteredMemberRefList<T> GetMembersOfType() const + RefPtr<Decl>* Adjust(RefPtr<Decl>* ptr, RefPtr<Decl>* end) const + { + while (ptr != end) { - return FilteredMemberRefList<T>(GetDecl()->Members, substitutions); + DeclRef declRef(ptr->Ptr(), substitutions); + if (declRef.As<T>()) + return ptr; + ptr++; } + return end; + } + }; - }; + struct ContainerDeclRef : DeclRef + { + SLANG_DECLARE_DECL_REF(ContainerDecl); - // - // Type Expressions - // + FilteredMemberRefList<DeclRef> GetMembers() const + { + return FilteredMemberRefList<DeclRef>(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<typename T> + FilteredMemberRefList<T> GetMembersOfType() const { - TypeExp() {} - TypeExp(TypeExp const& other) - : exp(other.exp) - , type(other.type) - {} - explicit TypeExp(RefPtr<ExpressionSyntaxNode> exp) - : exp(exp) - {} - TypeExp(RefPtr<ExpressionSyntaxNode> exp, RefPtr<ExpressionType> type) - : exp(exp) - , type(type) - {} + return FilteredMemberRefList<T>(GetDecl()->Members, substitutions); + } - RefPtr<ExpressionSyntaxNode> exp; - RefPtr<ExpressionType> type; + }; - bool Equals(ExpressionType* other) { - return type->Equals(other); - } - bool Equals(RefPtr<ExpressionType> other) { - return type->Equals(other.Ptr()); - } - ExpressionType* Ptr() { return type.Ptr(); } - operator RefPtr<ExpressionType>() - { - 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<ExpressionSyntaxNode> exp) + : exp(exp) + {} + TypeExp(RefPtr<ExpressionSyntaxNode> exp, RefPtr<ExpressionType> type) + : exp(exp) + , type(type) + {} + + RefPtr<ExpressionSyntaxNode> exp; + RefPtr<ExpressionType> type; + + bool Equals(ExpressionType* other) { + return type->Equals(other); + } + bool Equals(RefPtr<ExpressionType> other) { + return type->Equals(other.Ptr()); + } + ExpressionType* Ptr() { return type.Ptr(); } + operator RefPtr<ExpressionType>() + { + 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<ExpressionSyntaxNode> Expr; - }; + ExpressionType* getType() { return Type.type.Ptr(); } - struct VarDeclBaseRef : DeclRef - { - SLANG_DECLARE_DECL_REF(VarDeclBase); + // Initializer expression (optional) + RefPtr<ExpressionSyntaxNode> Expr; + }; - RefPtr<ExpressionType> GetType() const { return Substitute(GetDecl()->Type); } + struct VarDeclBaseRef : DeclRef + { + SLANG_DECLARE_DECL_REF(VarDeclBase); - RefPtr<ExpressionSyntaxNode> getInitExpr() const { return Substitute(GetDecl()->Expr); } - }; + RefPtr<ExpressionType> GetType() const { return Substitute(GetDecl()->Type); } - // A field of a `struct` type - class StructField : public VarDeclBase - { - public: - StructField() - {} - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + RefPtr<ExpressionSyntaxNode> 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<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - struct ExtensionDeclRef : AggTypeDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ExtensionDecl); + struct ExtensionDeclRef : AggTypeDeclBaseRef + { + SLANG_DECLARE_DECL_REF(ExtensionDecl); - RefPtr<ExpressionType> GetTargetType() const { return Substitute(GetDecl()->targetType); } - }; + RefPtr<ExpressionType> 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<StructField> GetFields() - { - return GetMembersOfType<StructField>(); - } - StructField* FindField(String name) + // extensions that might apply to this declaration + ExtensionDecl* candidateExtensions = nullptr; + FilteredMemberList<StructField> GetFields() + { + return GetMembersOfType<StructField>(); + } + 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; } - }; - - class StructSyntaxNode : public AggTypeDecl - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + ExtensionDecl* GetCandidateExtensions() const { return GetDecl()->candidateExtensions; } + }; - struct StructDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(StructSyntaxNode); + class StructSyntaxNode : public AggTypeDecl + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - FilteredMemberRefList<FieldDeclRef> GetFields() const { return GetMembersOfType<FieldDeclRef>(); } - }; + struct StructDeclRef : public AggTypeDeclRef + { + SLANG_DECLARE_DECL_REF(StructSyntaxNode); - class ClassSyntaxNode : public AggTypeDecl - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + FilteredMemberRefList<FieldDeclRef> GetFields() const { return GetMembersOfType<FieldDeclRef>(); } + }; - struct ClassDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(ClassSyntaxNode); + class ClassSyntaxNode : public AggTypeDecl + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - FilteredMemberRefList<FieldDeclRef> GetFields() const { return GetMembersOfType<FieldDeclRef>(); } - }; + struct ClassDeclRef : public AggTypeDeclRef + { + SLANG_DECLARE_DECL_REF(ClassSyntaxNode); - // An interface which other types can conform to - class InterfaceDecl : public AggTypeDecl - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + FilteredMemberRefList<FieldDeclRef> GetFields() const { return GetMembersOfType<FieldDeclRef>(); } + }; - struct InterfaceDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(InterfaceDecl); - }; + // An interface which other types can conform to + class InterfaceDecl : public AggTypeDecl + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; + 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; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + // 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; - struct InheritanceDeclRef : public DeclRef - { - SLANG_DECLARE_DECL_REF(InheritanceDecl); + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - RefPtr<ExpressionType> getBaseType() { return Substitute(GetDecl()->base.type); } - }; + struct InheritanceDeclRef : public DeclRef + { + SLANG_DECLARE_DECL_REF(InheritanceDecl); - // TODO: may eventually need sub-classes for explicit/direct vs. implicit/indirect inheritance + RefPtr<ExpressionType> getBaseType() { return Substitute(GetDecl()->base.type); } + }; + // 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 - { - }; - struct SimpleTypeDeclRef : DeclRef - { - SLANG_DECLARE_DECL_REF(SimpleTypeDecl) - }; + // A declaration that represents a simple (non-aggregate) type + class SimpleTypeDecl : public Decl + { + }; - // A `typedef` declaration - class TypeDefDecl : public SimpleTypeDecl - { - public: - TypeExp Type; + struct SimpleTypeDeclRef : DeclRef + { + SLANG_DECLARE_DECL_REF(SimpleTypeDecl) + }; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + // A `typedef` declaration + class TypeDefDecl : public SimpleTypeDecl + { + public: + TypeExp Type; - struct TypeDefDeclRef : SimpleTypeDeclRef - { - SLANG_DECLARE_DECL_REF(TypeDefDecl); + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - RefPtr<ExpressionType> GetType() const { return Substitute(GetDecl()->Type); } - }; + struct TypeDefDeclRef : SimpleTypeDeclRef + { + SLANG_DECLARE_DECL_REF(TypeDefDecl); - // A type alias of some kind (e.g., via `typedef`) - class NamedExpressionType : public ExpressionType - { - public: - NamedExpressionType(TypeDefDeclRef declRef) - : declRef(declRef) - {} + RefPtr<ExpressionType> GetType() const { return Substitute(GetDecl()->Type); } + }; - TypeDefDeclRef declRef; + // A type alias of some kind (e.g., via `typedef`) + class NamedExpressionType : public ExpressionType + { + public: + NamedExpressionType(TypeDefDeclRef declRef) + : declRef(declRef) + {} - virtual String ToString() override; + TypeDefDeclRef declRef; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + virtual String ToString() override; + protected: + virtual bool EqualsImpl(ExpressionType * type) override; + virtual ExpressionType* CreateCanonicalType() override; + virtual int GetHashCode() override; + }; - class StatementSyntaxNode : public ModifiableSyntaxNode - { - public: - }; - // A scope for local declarations (e.g., as part of a statement) - class ScopeDecl : public ContainerDecl - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class StatementSyntaxNode : public ModifiableSyntaxNode + { + public: + }; - class ScopeStmt : public StatementSyntaxNode - { - public: - RefPtr<ScopeDecl> scopeDecl; - }; + // A scope for local declarations (e.g., as part of a statement) + class ScopeDecl : public ContainerDecl + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class BlockStatementSyntaxNode : public ScopeStmt - { - public: - List<RefPtr<StatementSyntaxNode>> Statements; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class ScopeStmt : public StatementSyntaxNode + { + public: + RefPtr<ScopeDecl> scopeDecl; + }; - class UnparsedStmt : public StatementSyntaxNode - { - public: - // The tokens that were contained between `{` and `}` - List<Token> tokens; + class BlockStatementSyntaxNode : public ScopeStmt + { + public: + List<RefPtr<StatementSyntaxNode>> Statements; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class UnparsedStmt : public StatementSyntaxNode + { + public: + // The tokens that were contained between `{` and `}` + List<Token> tokens; - class ParameterSyntaxNode : public VarDeclBase - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - struct ParamDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ParameterSyntaxNode); - }; + class ParameterSyntaxNode : public VarDeclBase + { + public: + virtual RefPtr<SyntaxNode> 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<ParameterSyntaxNode> GetParameters() - { - return GetMembersOfType<ParameterSyntaxNode>(); - } - 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<ParameterSyntaxNode> GetParameters() { - SLANG_DECLARE_DECL_REF(CallableDecl); - - RefPtr<ExpressionType> GetResultType() const - { - return Substitute(GetDecl()->ReturnType.type.Ptr()); - } - - FilteredMemberRefList<ParamDeclRef> GetParameters() - { - return GetMembersOfType<ParamDeclRef>(); - } - }; + return GetMembersOfType<ParameterSyntaxNode>(); + } + 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<StatementSyntaxNode> Body; - }; + struct CallableDeclRef : ContainerDeclRef + { + SLANG_DECLARE_DECL_REF(CallableDecl); - struct FuncDeclBaseRef : CallableDeclRef + RefPtr<ExpressionType> 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<ParamDeclRef> GetParameters() { - public: - CallableDeclRef declRef; - - virtual String ToString() override; - protected: - virtual bool EqualsImpl(ExpressionType * type) override; - virtual ExpressionType* CreateCanonicalType() override; - virtual int GetHashCode() override; - }; + return GetMembersOfType<ParamDeclRef>(); + } + }; - // A constructor/initializer to create instances of a type - class ConstructorDecl : public FunctionDeclBase - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) 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<StatementSyntaxNode> Body; + }; - struct ConstructorDeclRef : FuncDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ConstructorDecl); - }; + 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - // A subscript operation used to index instances of a type - class SubscriptDecl : public CallableDecl - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + struct ConstructorDeclRef : FuncDeclBaseRef + { + SLANG_DECLARE_DECL_REF(ConstructorDecl); + }; - struct SubscriptDeclRef : CallableDeclRef - { - SLANG_DECLARE_DECL_REF(SubscriptDecl); - }; + // A subscript operation used to index instances of a type + class SubscriptDecl : public CallableDecl + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - // An "accessor" for a subscript or property - class AccessorDecl : public FunctionDeclBase - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + struct SubscriptDeclRef : CallableDeclRef + { + SLANG_DECLARE_DECL_REF(SubscriptDecl); + }; - class GetterDecl : public AccessorDecl - { - }; + // An "accessor" for a subscript or property + class AccessorDecl : public FunctionDeclBase + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class SetterDecl : public AccessorDecl - { - }; + class GetterDecl : public AccessorDecl + { + }; - // + class SetterDecl : public AccessorDecl + { + }; - class FunctionSyntaxNode : public FunctionDeclBase - { - public: - String InternalName; - bool IsInline() { return HasModifier<InlineModifier>(); } - bool IsExtern() { return HasModifier<ExternModifier>(); } - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - FunctionSyntaxNode() - { - } - }; + // - struct FuncDeclRef : FuncDeclBaseRef + class FunctionSyntaxNode : public FunctionDeclBase + { + public: + String InternalName; + bool IsInline() { return HasModifier<InlineModifier>(); } + bool IsExtern() { return HasModifier<ExternModifier>(); } + virtual RefPtr<SyntaxNode> 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<Scope> parent; - // The next sibling of this scope (a peer for lookup) - RefPtr<Scope> nextSibling; + struct Scope : public RefObject + { + // The parent of this scope (where lookup should go if nothing is found locally) + RefPtr<Scope> 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<Scope> nextSibling; - // Base class for expressions that will reference declarations - class DeclRefExpr : public ExpressionSyntaxNode - { - public: - // The scope in which to perform lookup - RefPtr<Scope> 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> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<Breadcrumb> next; - - Breadcrumb(Kind kind, DeclRef declRef, RefPtr<Breadcrumb> 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<Breadcrumb> 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<Breadcrumb> breadcrumbs; - - LookupResultItem() = default; - explicit LookupResultItem(DeclRef declRef) - : declRef(declRef) - {} - LookupResultItem(DeclRef declRef, RefPtr<Breadcrumb> breadcrumbs) - : declRef(declRef) - , breadcrumbs(breadcrumbs) + Breadcrumb(Kind kind, DeclRef declRef, RefPtr<Breadcrumb> 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<Breadcrumb> breadcrumbs; + + LookupResultItem() = default; + explicit LookupResultItem(DeclRef declRef) + : declRef(declRef) + {} + LookupResultItem(DeclRef declRef, RefPtr<Breadcrumb> breadcrumbs) + : declRef(declRef) + , breadcrumbs(breadcrumbs) + {} + }; + + + // Result of looking up a name in some lexical/semantic environment. + // Can be used to enumerate all the declarations matching that name, + // in the case where the result is overloaded. + struct LookupResult + { + // The one item that was found, in the smple case + LookupResultItem item; - // All of the items that were found, in the complex case. - // Note: if there was no overloading, then this list isn't - // used at all, to avoid allocation. - List<LookupResultItem> items; + // All of the items that were found, in the complex case. + // Note: if there was no overloading, then this list isn't + // used at all, to avoid allocation. + List<LookupResultItem> items; - // 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> scope = nullptr; - RefPtr<Scope> endScope = nullptr; + struct LookupRequest + { + RefPtr<Scope> scope = nullptr; + RefPtr<Scope> 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<ExpressionSyntaxNode> 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<ExpressionSyntaxNode> base; - // The lookup result that was ambiguous - LookupResult lookupResult2; + // The lookup result that was ambiguous + LookupResult lookupResult2; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - // An initializer list, e.g. `{ 1, 2, 3 }` - class InitializerListExpr : public ExpressionSyntaxNode - { - public: - List<RefPtr<ExpressionSyntaxNode>> 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<RefPtr<ExpressionSyntaxNode>> args; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<ExpressionSyntaxNode> FunctionExpr; - List<RefPtr<ExpressionSyntaxNode>> Arguments; - }; + // A base expression being applied to arguments: covers + // both ordinary `()` function calls and `<>` generic application + class AppExprBase : public ExpressionSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> FunctionExpr; + List<RefPtr<ExpressionSyntaxNode>> Arguments; + }; - class InvokeExpressionSyntaxNode : public AppExprBase - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class InvokeExpressionSyntaxNode : public AppExprBase + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class OperatorExpressionSyntaxNode : public InvokeExpressionSyntaxNode - { - public: + class OperatorExpressionSyntaxNode : public InvokeExpressionSyntaxNode + { + public: // Operator Operator; -// void SetOperator(RefPtr<Scope> scope, Slang::Compiler::Operator op); - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; +// void SetOperator(RefPtr<Scope> scope, Slang::Operator op); + virtual RefPtr<SyntaxNode> 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<ExpressionSyntaxNode> BaseExpression; - RefPtr<ExpressionSyntaxNode> IndexExpression; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class IndexExpressionSyntaxNode : public ExpressionSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> BaseExpression; + RefPtr<ExpressionSyntaxNode> IndexExpression; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class MemberExpressionSyntaxNode : public DeclRefExpr - { - public: - RefPtr<ExpressionSyntaxNode> BaseExpression; - String MemberName; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class MemberExpressionSyntaxNode : public DeclRefExpr + { + public: + RefPtr<ExpressionSyntaxNode> BaseExpression; + String MemberName; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class SwizzleExpr : public ExpressionSyntaxNode - { - public: - RefPtr<ExpressionSyntaxNode> base; - int elementCount; - int elementIndices[4]; + class SwizzleExpr : public ExpressionSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> base; + int elementCount; + int elementIndices[4]; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - // A dereference of a pointer or pointer-like type - class DerefExpr : public ExpressionSyntaxNode - { - public: - RefPtr<ExpressionSyntaxNode> base; + // A dereference of a pointer or pointer-like type + class DerefExpr : public ExpressionSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> base; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class TypeCastExpressionSyntaxNode : public ExpressionSyntaxNode - { - public: - TypeExp TargetType; - RefPtr<ExpressionSyntaxNode> Expression; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class TypeCastExpressionSyntaxNode : public ExpressionSyntaxNode + { + public: + TypeExp TargetType; + RefPtr<ExpressionSyntaxNode> Expression; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class SelectExpressionSyntaxNode : public OperatorExpressionSyntaxNode - { - public: - }; + class SelectExpressionSyntaxNode : public OperatorExpressionSyntaxNode + { + public: + }; - class EmptyStatementSyntaxNode : public StatementSyntaxNode - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class EmptyStatementSyntaxNode : public StatementSyntaxNode + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class DiscardStatementSyntaxNode : public StatementSyntaxNode - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class DiscardStatementSyntaxNode : public StatementSyntaxNode + { + public: + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - struct Variable : public VarDeclBase - { - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + struct Variable : public VarDeclBase + { + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class VarDeclrStatementSyntaxNode : public StatementSyntaxNode + class VarDeclrStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr<DeclBase> decl; + virtual RefPtr<SyntaxNode> 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<FunctionSyntaxNode> GetFunctions() { - public: - RefPtr<DeclBase> decl; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + return GetMembersOfType<FunctionSyntaxNode>(); + } - // A "module" of code (essentiately, a single translation unit) - // that provides a scope for some number of declarations. - class ProgramSyntaxNode : public ContainerDecl + FilteredMemberList<ClassSyntaxNode> GetClasses() { - public: - // Access members of specific types - FilteredMemberList<FunctionSyntaxNode> GetFunctions() - { - return GetMembersOfType<FunctionSyntaxNode>(); - } + return GetMembersOfType<ClassSyntaxNode>(); + } + FilteredMemberList<StructSyntaxNode> GetStructs() + { + return GetMembersOfType<StructSyntaxNode>(); + } + FilteredMemberList<TypeDefDecl> GetTypeDefs() + { + return GetMembersOfType<TypeDefDecl>(); + } - FilteredMemberList<ClassSyntaxNode> GetClasses() - { - return GetMembersOfType<ClassSyntaxNode>(); - } - FilteredMemberList<StructSyntaxNode> GetStructs() - { - return GetMembersOfType<StructSyntaxNode>(); - } - FilteredMemberList<TypeDefDecl> GetTypeDefs() - { - return GetMembersOfType<TypeDefDecl>(); - } + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr<SyntaxNode> 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> scope; - // The scope that we want to import into - RefPtr<Scope> scope; + // The module that actually got imported + RefPtr<ProgramSyntaxNode> importedModuleDecl; - // The module that actually got imported - RefPtr<ProgramSyntaxNode> importedModuleDecl; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class IfStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> Predicate; + RefPtr<StatementSyntaxNode> PositiveStatement; + RefPtr<StatementSyntaxNode> NegativeStatement; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; + + // A statement that can be escaped with a `break` + class BreakableStmt : public ScopeStmt + {}; + + class SwitchStmt : public BreakableStmt + { + public: + RefPtr<ExpressionSyntaxNode> condition; + RefPtr<StatementSyntaxNode> body; - class IfStatementSyntaxNode : public StatementSyntaxNode - { - public: - RefPtr<ExpressionSyntaxNode> Predicate; - RefPtr<StatementSyntaxNode> PositiveStatement; - RefPtr<StatementSyntaxNode> NegativeStatement; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<ExpressionSyntaxNode> condition; - RefPtr<StatementSyntaxNode> body; + // a `case` statement inside a `switch` + class CaseStmt : public CaseStmtBase + { + public: + RefPtr<ExpressionSyntaxNode> expr; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<SyntaxNode> 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<ExpressionSyntaxNode> expr; + class ForStatementSyntaxNode : public LoopStmt + { + public: + RefPtr<StatementSyntaxNode> InitialStatement; + RefPtr<ExpressionSyntaxNode> SideEffectExpression, PredicateExpression; + RefPtr<StatementSyntaxNode> Statement; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; + + class WhileStatementSyntaxNode : public LoopStmt + { + public: + RefPtr<ExpressionSyntaxNode> Predicate; + RefPtr<StatementSyntaxNode> Statement; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class DoWhileStatementSyntaxNode : public LoopStmt + { + public: + RefPtr<StatementSyntaxNode> Statement; + RefPtr<ExpressionSyntaxNode> Predicate; + virtual RefPtr<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class BreakStatementSyntaxNode : public JumpStmt + { + public: + virtual RefPtr<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class ForStatementSyntaxNode : public LoopStmt - { - public: - RefPtr<StatementSyntaxNode> InitialStatement; - RefPtr<ExpressionSyntaxNode> SideEffectExpression, PredicateExpression; - RefPtr<StatementSyntaxNode> Statement; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class ReturnStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> Expression; + virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class WhileStatementSyntaxNode : public LoopStmt - { - public: - RefPtr<ExpressionSyntaxNode> Predicate; - RefPtr<StatementSyntaxNode> Statement; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + class ExpressionStatementSyntaxNode : public StatementSyntaxNode + { + public: + RefPtr<ExpressionSyntaxNode> Expression; + virtual RefPtr<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class DoWhileStatementSyntaxNode : public LoopStmt - { - public: - RefPtr<StatementSyntaxNode> Statement; - RefPtr<ExpressionSyntaxNode> Predicate; - virtual RefPtr<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - class BreakStatementSyntaxNode : public JumpStmt - { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; - class ContinueStatementSyntaxNode : public JumpStmt - { - public: - virtual RefPtr<SyntaxNode> 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<ExpressionSyntaxNode> Expression; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + // Modifiers that affect the storage layout for matrices + class MatrixLayoutModifier : public Modifier {}; - class ExpressionStatementSyntaxNode : public StatementSyntaxNode - { - public: - RefPtr<ExpressionSyntaxNode> Expression; - virtual RefPtr<SyntaxNode> 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<SyntaxNode> 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<SyntaxNode> 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<RefPtr<ExpressionSyntaxNode>> 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<Decl> inner; - // HLSL `precise` modifier - class HLSLPreciseModifier : public Modifier {}; + virtual RefPtr<SyntaxNode> 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<RefPtr<ExpressionSyntaxNode>> 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<Decl> inner; + // The "initializer" for the parameter represents a default value + TypeExp initType; - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + virtual RefPtr<SyntaxNode> 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<SyntaxNode> 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<ExpressionType> GetSub() { return Substitute(GetDecl()->sub); } + RefPtr<ExpressionType> GetSup() { return Substitute(GetDecl()->sup); } + }; - GenericDeclRef declRef; - GenericDeclRef const& GetDeclRef() const { return declRef; } - virtual String ToString() override; + class GenericValueParamDecl : public VarDeclBase + { + public: + virtual RefPtr<SyntaxNode> 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<Val> 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<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; + }; - virtual RefPtr<SyntaxNode> 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<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; + sourceLanguage = language; + } - struct GenericTypeConstraintDeclRef : DeclRef + SyntaxVisitor(DiagnosticSink * sink) + : sink(sink) + {} + virtual RefPtr<ProgramSyntaxNode> VisitProgram(ProgramSyntaxNode* program) { - SLANG_DECLARE_DECL_REF(GenericTypeConstraintDecl); - - RefPtr<ExpressionType> GetSub() { return Substitute(GetDecl()->sub); } - RefPtr<ExpressionType> GetSup() { return Substitute(GetDecl()->sup); } - }; + for (auto & m : program->Members) + m = m->Accept(this).As<Decl>(); + return program; + } + virtual void visitImportDecl(ImportDecl * decl) = 0; - class GenericValueParamDecl : public VarDeclBase + virtual RefPtr<FunctionSyntaxNode> VisitFunction(FunctionSyntaxNode* func) { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; - - struct GenericValueParamDeclRef : VarDeclBaseRef + func->ReturnType = func->ReturnType.Accept(this); + for (auto & member : func->Members) + member = member->Accept(this).As<Decl>(); + if (func->Body) + func->Body = func->Body->Accept(this).As<BlockStatementSyntaxNode>(); + return func; + } + virtual RefPtr<ScopeDecl> 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<StructSyntaxNode> 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<Val> 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<Decl>(); + return s; + } + virtual RefPtr<ClassSyntaxNode> 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<SyntaxNode> 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<Decl>(); + return s; + } + virtual RefPtr<GenericDecl> VisitGenericDecl(GenericDecl * decl) { - public: - virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override; - }; - - // - - class SyntaxVisitor : public Object + for (auto & m : decl->Members) + m = m->Accept(this).As<Decl>(); + decl->inner = decl->inner->Accept(this).As<Decl>(); + return decl; + } + virtual RefPtr<TypeDefDecl> 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<ProgramSyntaxNode> VisitProgram(ProgramSyntaxNode* program) - { - for (auto & m : program->Members) - m = m->Accept(this).As<Decl>(); - return program; - } - - virtual void visitImportDecl(ImportDecl * decl) = 0; - - virtual RefPtr<FunctionSyntaxNode> VisitFunction(FunctionSyntaxNode* func) - { - func->ReturnType = func->ReturnType.Accept(this); - for (auto & member : func->Members) - member = member->Accept(this).As<Decl>(); - if (func->Body) - func->Body = func->Body->Accept(this).As<BlockStatementSyntaxNode>(); - return func; - } - virtual RefPtr<ScopeDecl> 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<StructSyntaxNode> VisitStruct(StructSyntaxNode * s) - { - for (auto & f : s->Members) - f = f->Accept(this).As<Decl>(); - return s; - } - virtual RefPtr<ClassSyntaxNode> VisitClass(ClassSyntaxNode * s) - { - for (auto & f : s->Members) - f = f->Accept(this).As<Decl>(); - return s; - } - virtual RefPtr<GenericDecl> VisitGenericDecl(GenericDecl * decl) - { - for (auto & m : decl->Members) - m = m->Accept(this).As<Decl>(); - decl->inner = decl->inner->Accept(this).As<Decl>(); - return decl; - } - virtual RefPtr<TypeDefDecl> VisitTypeDefDecl(TypeDefDecl* decl) - { - decl->Type = decl->Type.Accept(this); - return decl; - } - virtual RefPtr<StatementSyntaxNode> VisitDiscardStatement(DiscardStatementSyntaxNode * stmt) - { - return stmt; - } - virtual RefPtr<StructField> VisitStructField(StructField * f) - { - f->Type = f->Type.Accept(this); - return f; - } - virtual RefPtr<StatementSyntaxNode> VisitBlockStatement(BlockStatementSyntaxNode* stmt) - { - for (auto & s : stmt->Statements) - s = s->Accept(this).As<StatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitBreakStatement(BreakStatementSyntaxNode* stmt) - { - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitContinueStatement(ContinueStatementSyntaxNode* stmt) - { - return stmt; - } + decl->Type = decl->Type.Accept(this); + return decl; + } + virtual RefPtr<StatementSyntaxNode> VisitDiscardStatement(DiscardStatementSyntaxNode * stmt) + { + return stmt; + } + virtual RefPtr<StructField> VisitStructField(StructField * f) + { + f->Type = f->Type.Accept(this); + return f; + } + virtual RefPtr<StatementSyntaxNode> VisitBlockStatement(BlockStatementSyntaxNode* stmt) + { + for (auto & s : stmt->Statements) + s = s->Accept(this).As<StatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitBreakStatement(BreakStatementSyntaxNode* stmt) + { + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitContinueStatement(ContinueStatementSyntaxNode* stmt) + { + return stmt; + } - virtual RefPtr<StatementSyntaxNode> VisitDoWhileStatement(DoWhileStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitEmptyStatement(EmptyStatementSyntaxNode* stmt) - { - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitForStatement(ForStatementSyntaxNode* stmt) - { - if (stmt->InitialStatement) - stmt->InitialStatement = stmt->InitialStatement->Accept(this).As<StatementSyntaxNode>(); - if (stmt->PredicateExpression) - stmt->PredicateExpression = stmt->PredicateExpression->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->SideEffectExpression) - stmt->SideEffectExpression = stmt->SideEffectExpression->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitIfStatement(IfStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->PositiveStatement) - stmt->PositiveStatement = stmt->PositiveStatement->Accept(this).As<StatementSyntaxNode>(); - if (stmt->NegativeStatement) - stmt->NegativeStatement = stmt->NegativeStatement->Accept(this).As<StatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<SwitchStmt> VisitSwitchStmt(SwitchStmt* stmt) - { - if (stmt->condition) - stmt->condition = stmt->condition->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->body) - stmt->body = stmt->body->Accept(this).As<BlockStatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<CaseStmt> VisitCaseStmt(CaseStmt* stmt) - { - if (stmt->expr) - stmt->expr = stmt->expr->Accept(this).As<ExpressionSyntaxNode>(); - return stmt; - } - virtual RefPtr<DefaultStmt> VisitDefaultStmt(DefaultStmt* stmt) - { - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitReturnStatement(ReturnStatementSyntaxNode* stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitVarDeclrStatement(VarDeclrStatementSyntaxNode* stmt) - { - stmt->decl = stmt->decl->Accept(this).As<DeclBase>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitWhileStatement(WhileStatementSyntaxNode* stmt) - { - if (stmt->Predicate) - stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); - if (stmt->Statement) - stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); - return stmt; - } - virtual RefPtr<StatementSyntaxNode> VisitExpressionStatement(ExpressionStatementSyntaxNode* stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); - return stmt; - } + virtual RefPtr<StatementSyntaxNode> VisitDoWhileStatement(DoWhileStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitEmptyStatement(EmptyStatementSyntaxNode* stmt) + { + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitForStatement(ForStatementSyntaxNode* stmt) + { + if (stmt->InitialStatement) + stmt->InitialStatement = stmt->InitialStatement->Accept(this).As<StatementSyntaxNode>(); + if (stmt->PredicateExpression) + stmt->PredicateExpression = stmt->PredicateExpression->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->SideEffectExpression) + stmt->SideEffectExpression = stmt->SideEffectExpression->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitIfStatement(IfStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->PositiveStatement) + stmt->PositiveStatement = stmt->PositiveStatement->Accept(this).As<StatementSyntaxNode>(); + if (stmt->NegativeStatement) + stmt->NegativeStatement = stmt->NegativeStatement->Accept(this).As<StatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<SwitchStmt> VisitSwitchStmt(SwitchStmt* stmt) + { + if (stmt->condition) + stmt->condition = stmt->condition->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->body) + stmt->body = stmt->body->Accept(this).As<BlockStatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<CaseStmt> VisitCaseStmt(CaseStmt* stmt) + { + if (stmt->expr) + stmt->expr = stmt->expr->Accept(this).As<ExpressionSyntaxNode>(); + return stmt; + } + virtual RefPtr<DefaultStmt> VisitDefaultStmt(DefaultStmt* stmt) + { + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitReturnStatement(ReturnStatementSyntaxNode* stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitVarDeclrStatement(VarDeclrStatementSyntaxNode* stmt) + { + stmt->decl = stmt->decl->Accept(this).As<DeclBase>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitWhileStatement(WhileStatementSyntaxNode* stmt) + { + if (stmt->Predicate) + stmt->Predicate = stmt->Predicate->Accept(this).As<ExpressionSyntaxNode>(); + if (stmt->Statement) + stmt->Statement = stmt->Statement->Accept(this).As<StatementSyntaxNode>(); + return stmt; + } + virtual RefPtr<StatementSyntaxNode> VisitExpressionStatement(ExpressionStatementSyntaxNode* stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); + return stmt; + } - virtual RefPtr<ExpressionSyntaxNode> VisitOperatorExpression(OperatorExpressionSyntaxNode* expr) - { - for (auto && child : expr->Arguments) - child->Accept(this); - return expr; - } - virtual RefPtr<ExpressionSyntaxNode> VisitConstantExpression(ConstantExpressionSyntaxNode* expr) - { - return expr; - } - virtual RefPtr<ExpressionSyntaxNode> VisitIndexExpression(IndexExpressionSyntaxNode* expr) - { - if (expr->BaseExpression) - expr->BaseExpression = expr->BaseExpression->Accept(this).As<ExpressionSyntaxNode>(); - if (expr->IndexExpression) - expr->IndexExpression = expr->IndexExpression->Accept(this).As<ExpressionSyntaxNode>(); - return expr; - } - virtual RefPtr<ExpressionSyntaxNode> VisitMemberExpression(MemberExpressionSyntaxNode * stmt) - { - if (stmt->BaseExpression) - stmt->BaseExpression = stmt->BaseExpression->Accept(this).As<ExpressionSyntaxNode>(); - return stmt; - } - virtual RefPtr<ExpressionSyntaxNode> VisitSwizzleExpression(SwizzleExpr * expr) - { - if (expr->base) - expr->base->Accept(this); - return expr; - } - virtual RefPtr<ExpressionSyntaxNode> VisitInvokeExpression(InvokeExpressionSyntaxNode* stmt) - { - stmt->FunctionExpr->Accept(this); - for (auto & arg : stmt->Arguments) - arg = arg->Accept(this).As<ExpressionSyntaxNode>(); - return stmt; - } - virtual RefPtr<ExpressionSyntaxNode> VisitTypeCastExpression(TypeCastExpressionSyntaxNode * stmt) - { - if (stmt->Expression) - stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); - return stmt->Expression; - } - virtual RefPtr<ExpressionSyntaxNode> VisitVarExpression(VarExpressionSyntaxNode* expr) - { - return expr; - } + virtual RefPtr<ExpressionSyntaxNode> VisitOperatorExpression(OperatorExpressionSyntaxNode* expr) + { + for (auto && child : expr->Arguments) + child->Accept(this); + return expr; + } + virtual RefPtr<ExpressionSyntaxNode> VisitConstantExpression(ConstantExpressionSyntaxNode* expr) + { + return expr; + } + virtual RefPtr<ExpressionSyntaxNode> VisitIndexExpression(IndexExpressionSyntaxNode* expr) + { + if (expr->BaseExpression) + expr->BaseExpression = expr->BaseExpression->Accept(this).As<ExpressionSyntaxNode>(); + if (expr->IndexExpression) + expr->IndexExpression = expr->IndexExpression->Accept(this).As<ExpressionSyntaxNode>(); + return expr; + } + virtual RefPtr<ExpressionSyntaxNode> VisitMemberExpression(MemberExpressionSyntaxNode * stmt) + { + if (stmt->BaseExpression) + stmt->BaseExpression = stmt->BaseExpression->Accept(this).As<ExpressionSyntaxNode>(); + return stmt; + } + virtual RefPtr<ExpressionSyntaxNode> VisitSwizzleExpression(SwizzleExpr * expr) + { + if (expr->base) + expr->base->Accept(this); + return expr; + } + virtual RefPtr<ExpressionSyntaxNode> VisitInvokeExpression(InvokeExpressionSyntaxNode* stmt) + { + stmt->FunctionExpr->Accept(this); + for (auto & arg : stmt->Arguments) + arg = arg->Accept(this).As<ExpressionSyntaxNode>(); + return stmt; + } + virtual RefPtr<ExpressionSyntaxNode> VisitTypeCastExpression(TypeCastExpressionSyntaxNode * stmt) + { + if (stmt->Expression) + stmt->Expression = stmt->Expression->Accept(this).As<ExpressionSyntaxNode>(); + return stmt->Expression; + } + virtual RefPtr<ExpressionSyntaxNode> VisitVarExpression(VarExpressionSyntaxNode* expr) + { + return expr; + } - virtual RefPtr<ParameterSyntaxNode> VisitParameter(ParameterSyntaxNode* param) - { - return param; - } - virtual RefPtr<ExpressionSyntaxNode> VisitGenericApp(GenericAppExpr* type) - { - return type; - } + virtual RefPtr<ParameterSyntaxNode> VisitParameter(ParameterSyntaxNode* param) + { + return param; + } + virtual RefPtr<ExpressionSyntaxNode> VisitGenericApp(GenericAppExpr* type) + { + return type; + } - virtual RefPtr<Variable> VisitDeclrVariable(Variable* dclr) - { - if (dclr->Expr) - dclr->Expr = dclr->Expr->Accept(this).As<ExpressionSyntaxNode>(); - return dclr; - } + virtual RefPtr<Variable> VisitDeclrVariable(Variable* dclr) + { + if (dclr->Expr) + dclr->Expr = dclr->Expr->Accept(this).As<ExpressionSyntaxNode>(); + return dclr; + } - virtual TypeExp VisitTypeExp(TypeExp const& typeExp) + virtual TypeExp VisitTypeExp(TypeExp const& typeExp) + { + TypeExp result = typeExp; + result.exp = typeExp.exp->Accept(this).As<ExpressionSyntaxNode>(); + if (auto typeType = result.exp->Type.type.As<TypeType>()) { - TypeExp result = typeExp; - result.exp = typeExp.exp->Accept(this).As<ExpressionSyntaxNode>(); - if (auto typeType = result.exp->Type.type.As<TypeType>()) - { - 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<ExpressionSyntaxNode> VisitSharedTypeExpr(SharedTypeExpr* typeExpr) - { - return typeExpr; - } + virtual RefPtr<ExpressionSyntaxNode> 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<ExpressionSyntaxNode> 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> decl, - RefPtr<BuiltinTypeModifier> modifier); - void RegisterMagicDecl( - RefPtr<Decl> decl, - RefPtr<MagicTypeModifier> modifier); - - // Look up a magic declaration by its name - RefPtr<Decl> findMagicDecl( - String const& name); - - // Create an instance of a syntax class by name - SyntaxNodeBase* createInstanceOfSyntaxClassByName( - String const& name); - - } -} + virtual RefPtr<ExpressionSyntaxNode> 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> decl, + RefPtr<BuiltinTypeModifier> modifier); + void RegisterMagicDecl( + RefPtr<Decl> decl, + RefPtr<MagicTypeModifier> modifier); + + // Look up a magic declaration by its name + RefPtr<Decl> 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 |
