// slang-ast-type.h #pragma once #include "slang-ast-base.h" #include "slang-ast-decl.h" // #include "slang-ast-type.h.fiddle" FIDDLE() namespace Slang { // Syntax class definitions for types. // The type of a reference to an overloaded name FIDDLE() class OverloadGroupType : public Type { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); }; // The type of an initializer-list expression (before it has // been coerced to some other type) FIDDLE() class InitializerListType : public Type { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); }; // The type of an expression that was erroneous FIDDLE() class ErrorType : public Type { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; // The bottom/empty type that has no values. FIDDLE() class BottomType : public Type { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; // A type that takes the form of a reference to some declaration FIDDLE() class DeclRefType : public Type { FIDDLE(...) static Type* create(ASTBuilder* astBuilder, DeclRef declRef); DeclRef getDeclRef() const { return DeclRef(as(getOperand(0))); } DeclRefBase* getDeclRefBase() const { return as(getOperand(0)); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); DeclRefType(DeclRefBase* declRefBase) { setOperands(declRefBase); } }; template DeclRef isDeclRefTypeOf(Val* type) { if (auto declRefType = as(type)) { return declRefType->getDeclRef().template as(); } return DeclRef(); } bool isTypePack(Type* type); bool isAbstractTypePack(Type* type); // Base class for types that can be used in arithmetic expressions FIDDLE(abstract) class ArithmeticExpressionType : public DeclRefType { FIDDLE(...) BasicExpressionType* getScalarType(); // Overrides should be public so base classes can access BasicExpressionType* _getScalarTypeOverride(); }; FIDDLE() class BasicExpressionType : public ArithmeticExpressionType { FIDDLE(...) BaseType getBaseType() const; // Overrides should be public so base classes can access BasicExpressionType* _getScalarTypeOverride(); BasicExpressionType(DeclRefBase* inDeclRef) { setOperands(inDeclRef); } }; // Base type for things that are built in to the compiler, // and will usually have special behavior or a custom // mapping to the IR level. FIDDLE(abstract) class BuiltinType : public DeclRefType { FIDDLE(...) }; FIDDLE(abstract) class DataLayoutType : public BuiltinType { FIDDLE(...) }; FIDDLE() class IBufferDataLayoutType : public BuiltinType { FIDDLE(...) }; FIDDLE() class DefaultDataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class DefaultPushConstantDataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class Std430DataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class Std140DataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class ScalarDataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class CDataLayoutType : public DataLayoutType { FIDDLE(...) }; FIDDLE() class FeedbackType : public BuiltinType { FIDDLE(...) enum class Kind : uint8_t { MinMip, /// SAMPLER_FEEDBACK_MIN_MIP MipRegionUsed, /// SAMPLER_FEEDBACK_MIP_REGION_USED }; Kind getKind() const; }; FIDDLE(abstract) class TextureShapeType : public BuiltinType { FIDDLE(...) }; FIDDLE() class TextureShape1DType : public TextureShapeType { FIDDLE(...) }; FIDDLE() class TextureShape2DType : public TextureShapeType { FIDDLE(...) }; FIDDLE() class TextureShape3DType : public TextureShapeType { FIDDLE(...) }; FIDDLE() class TextureShapeCubeType : public TextureShapeType { FIDDLE(...) }; FIDDLE() class TextureShapeBufferType : public TextureShapeType { FIDDLE(...) }; // Resources that contain "elements" that can be fetched FIDDLE(abstract) class ResourceType : public BuiltinType { FIDDLE(...) bool isMultisample(); bool isArray(); bool isShadow(); bool isFeedback(); bool isCombined(); SlangResourceShape getBaseShape(); SlangResourceShape getShape(); SlangResourceAccess getAccess(); Type* getElementType(); void _toTextOverride(StringBuilder& out); }; FIDDLE(abstract) class TextureTypeBase : public ResourceType { FIDDLE(...) Val* getSampleCount(); Val* getFormat(); }; FIDDLE() class TextureType : public TextureTypeBase { FIDDLE(...) }; // This is a base type for `image*` types, as they exist in GLSL FIDDLE() class GLSLImageType : public TextureTypeBase { FIDDLE(...) }; FIDDLE() class SubpassInputType : public BuiltinType { FIDDLE(...) bool isMultisample(); Type* getElementType(); }; FIDDLE() class SamplerStateType : public BuiltinType { FIDDLE(...) // Returns flavor of sampler state of this type. SamplerStateFlavor getFlavor() const; }; // Other cases of generic types known to the compiler FIDDLE() class BuiltinGenericType : public BuiltinType { FIDDLE(...) Type* getElementType() const; }; // Types that behave like pointers, in that they can be // dereferenced (implicitly) to access members defined // in the element type. FIDDLE(abstract) class PointerLikeType : public BuiltinGenericType { FIDDLE(...) }; FIDDLE() class DynamicResourceType : public BuiltinType { FIDDLE(...) }; // HLSL buffer-type resources FIDDLE(abstract) class HLSLStructuredBufferTypeBase : public BuiltinGenericType { FIDDLE(...) }; FIDDLE() class HLSLStructuredBufferType : public HLSLStructuredBufferTypeBase { FIDDLE(...) }; FIDDLE() class HLSLRWStructuredBufferType : public HLSLStructuredBufferTypeBase { FIDDLE(...) }; FIDDLE() class HLSLRasterizerOrderedStructuredBufferType : public HLSLStructuredBufferTypeBase { FIDDLE(...) }; FIDDLE() class UntypedBufferResourceType : public BuiltinType { FIDDLE(...) }; FIDDLE() class HLSLByteAddressBufferType : public UntypedBufferResourceType { FIDDLE(...) }; FIDDLE() class HLSLRWByteAddressBufferType : public UntypedBufferResourceType { FIDDLE(...) }; FIDDLE() class HLSLRasterizerOrderedByteAddressBufferType : public UntypedBufferResourceType { FIDDLE(...) }; FIDDLE() class RaytracingAccelerationStructureType : public UntypedBufferResourceType { FIDDLE(...) }; FIDDLE() class HLSLAppendStructuredBufferType : public HLSLStructuredBufferTypeBase { FIDDLE(...) }; FIDDLE() class HLSLConsumeStructuredBufferType : public HLSLStructuredBufferTypeBase { FIDDLE(...) }; FIDDLE() class GLSLAtomicUintType : public BuiltinType { FIDDLE(...) }; FIDDLE() class HLSLPatchType : public BuiltinType { FIDDLE(...) Type* getElementType(); IntVal* getElementCount(); }; FIDDLE() class HLSLInputPatchType : public HLSLPatchType { FIDDLE(...) }; FIDDLE() class HLSLOutputPatchType : public HLSLPatchType { FIDDLE(...) }; // HLSL geometry shader output stream types FIDDLE() class HLSLStreamOutputType : public BuiltinGenericType { FIDDLE(...) }; FIDDLE() class HLSLPointStreamType : public HLSLStreamOutputType { FIDDLE(...) }; FIDDLE() class HLSLLineStreamType : public HLSLStreamOutputType { FIDDLE(...) }; FIDDLE() class HLSLTriangleStreamType : public HLSLStreamOutputType { FIDDLE(...) }; // mesh shader output types FIDDLE() class MeshOutputType : public BuiltinGenericType { FIDDLE(...) Type* getElementType(); IntVal* getMaxElementCount(); }; FIDDLE() class VerticesType : public MeshOutputType { FIDDLE(...) }; FIDDLE() class IndicesType : public MeshOutputType { FIDDLE(...) }; FIDDLE() class PrimitivesType : public MeshOutputType { FIDDLE(...) }; // FIDDLE() class GLSLInputAttachmentType : public BuiltinType { FIDDLE(...) }; FIDDLE() class DescriptorHandleType : public PointerLikeType { FIDDLE(...) }; // Base class for types used when desugaring parameter block // declarations, includeing HLSL `cbuffer` or GLSL `uniform` blocks. FIDDLE(abstract) class ParameterGroupType : public PointerLikeType { FIDDLE(...) }; FIDDLE() class UniformParameterGroupType : public ParameterGroupType { FIDDLE(...) Type* getLayoutType(); }; FIDDLE() class VaryingParameterGroupType : public ParameterGroupType { FIDDLE(...) }; // type for HLSL `cbuffer` declarations, and `ConstantBuffer` // ALso used for GLSL `uniform` blocks. FIDDLE() class ConstantBufferType : public UniformParameterGroupType { FIDDLE(...) }; // type for HLSL `tbuffer` declarations, and `TextureBuffer` FIDDLE() class TextureBufferType : public UniformParameterGroupType { FIDDLE(...) }; // type for GLSL `in` and `out` blocks FIDDLE() class GLSLInputParameterGroupType : public VaryingParameterGroupType { FIDDLE(...) }; FIDDLE() class GLSLOutputParameterGroupType : public VaryingParameterGroupType { FIDDLE(...) }; // type for GLSL `buffer` blocks FIDDLE() class GLSLShaderStorageBufferType : public PointerLikeType { FIDDLE(...) }; // type for Slang `ParameterBlock` type FIDDLE() class ParameterBlockType : public UniformParameterGroupType { FIDDLE(...) }; FIDDLE() class ArrayExpressionType : public DeclRefType { FIDDLE(...) bool isUnsized(); void _toTextOverride(StringBuilder& out); Type* getElementType(); IntVal* getElementCount(); }; FIDDLE() class AtomicType : public DeclRefType { FIDDLE(...) Type* getElementType(); }; FIDDLE() class CoopVectorExpressionType : public ArithmeticExpressionType { FIDDLE(...) void _toTextOverride(StringBuilder& out); BasicExpressionType* _getScalarTypeOverride(); Type* getElementType(); IntVal* getElementCount(); }; // 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)`. FIDDLE() class TypeType : public Type { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Type* getType() { return as(getOperand(0)); } TypeType(Type* type) { setOperands(type); } }; // A differential pair type, e.g., `__DifferentialPair` FIDDLE() class DifferentialPairType : public ArithmeticExpressionType { FIDDLE(...) Type* getPrimalType(); }; FIDDLE() class DifferentialPtrPairType : public ArithmeticExpressionType { FIDDLE(...) Type* getPrimalRefType(); }; FIDDLE() class DifferentiableType : public BuiltinType { FIDDLE(...) }; FIDDLE() class DifferentiablePtrType : public BuiltinType { FIDDLE(...) }; FIDDLE() class DefaultInitializableType : public BuiltinType { FIDDLE(...) }; // A vector type, e.g., `vector` FIDDLE() class VectorExpressionType : public ArithmeticExpressionType { FIDDLE(...) // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); BasicExpressionType* _getScalarTypeOverride(); Type* getElementType(); IntVal* getElementCount(); }; // A matrix type, e.g., `matrix` FIDDLE() class MatrixExpressionType : public ArithmeticExpressionType { FIDDLE(...) Type* getElementType(); IntVal* getRowCount(); IntVal* getColumnCount(); IntVal* getLayout(); Type* getRowType(); // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); BasicExpressionType* _getScalarTypeOverride(); private: Type* rowType = nullptr; }; FIDDLE() class TensorViewType : public BuiltinType { FIDDLE(...) Type* getElementType(); }; // Base class for built in string types FIDDLE(abstract) class StringTypeBase : public BuiltinType { FIDDLE(...) }; // The regular built-in `String` type FIDDLE() class StringType : public StringTypeBase { FIDDLE(...) }; // The string type native to the target FIDDLE() class NativeStringType : public StringTypeBase { FIDDLE(...) }; // The built-in `__Dynamic` type FIDDLE() class DynamicType : public BuiltinType { FIDDLE(...) }; // Type built-in `__EnumType` type FIDDLE() class EnumTypeType : public BuiltinType { FIDDLE(...) // TODO: provide accessors for the declaration, the "tag" type, etc. }; // Base class for types that map down to // simple pointers as part of code generation. FIDDLE() class PtrTypeBase : public BuiltinType { FIDDLE(...) // Get the type of the pointed-to value. Type* getValueType(); Val* getAccessQualifier(); Val* getAddressSpace(); std::optional tryGetAccessQualifierValue(); }; FIDDLE() class NoneType : public BuiltinType { FIDDLE(...) }; FIDDLE() class NullPtrType : public BuiltinType { FIDDLE(...) }; // A true (user-visible) pointer type, e.g., `T*` FIDDLE() class PtrType : public PtrTypeBase { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; /// A pointer-like type used to represent a parameter-passing mode. /// FIDDLE() class ParamPassingModeType : public PtrTypeBase { FIDDLE(...) }; // A type that represents the behind-the-scenes // logical pointer that is passed for an `out` // or `in out` parameter FIDDLE(abstract) class OutParamTypeBase : public ParamPassingModeType { FIDDLE(...) }; // The type for an output parameter, e.g., `out T` FIDDLE() class OutParamType : public OutParamTypeBase { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; using OutType = OutParamType; // The type for a mutable borrow input/output parameter, e.g., `in out T` FIDDLE() class BorrowInOutParamType : public OutParamTypeBase { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; // The type for a by-reference parameter, e.g., `ref T` FIDDLE() class RefParamType : public ParamPassingModeType { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; /// The type for a immutable borrow input parameter, e.g., `borrow T` /// /// Note that, despite the modifier currently used to represent /// this case in code, this is *not* comparable to the `ref` /// parameter-passing mode, and is instead an input-only /// equivalent of `inout`. /// FIDDLE() class BorrowInParamType : public ParamPassingModeType { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; /// A reference type that is explicitly named somewhere in code (`Ref`). /// /// The explicit reference types are distinct from the /// parameter-passing mode wrapper types like `RefParamType`. /// An explicit reference type is a type that code written in /// Slang is allowed to name (e.g., by having a function that /// returns a `Ref`), even if those uses may only occur /// in the core module. In constrast, the parameter-passing /// mode wrapper types should only ever be used as part of /// the encoding of a `FuncType`. /// FIDDLE() class ExplicitRefType : public PtrTypeBase { FIDDLE(...) void _toTextOverride(StringBuilder& out); }; FIDDLE() class OptionalType : public BuiltinType { FIDDLE(...) Type* getValueType(); }; // A raw-pointer reference to an managed value. FIDDLE() class NativeRefType : public BuiltinType { FIDDLE(...) Type* getValueType(); }; // A type alias of some kind (e.g., via `typedef`) FIDDLE() class NamedExpressionType : public Type { FIDDLE(...) DeclRef getDeclRef() { return as(getOperand(0)); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); NamedExpressionType(DeclRef inDeclRef) { setOperands(inDeclRef); } }; // A function type is defined by its parameter types // and its result type. FIDDLE() class FuncType : public Type { FIDDLE(...) // Construct a unary function FuncType(Type* paramType, Type* resultType, Type* errorType) { setOperands(paramType, resultType, errorType); } FuncType(ArrayView parameters, Type* result, Type* error) { for (auto paramType : parameters) m_operands.add(ValNodeOperand(paramType)); m_operands.add(ValNodeOperand(result)); m_operands.add(ValNodeOperand(error)); } OperandView getParamTypes() { return OperandView(this, 0, getOperandCount() - 2); } Index getParamCount() { return m_operands.getCount() - 2; } /// Get the type of one of the function's parameters, by index. /// /// The type returned by this function may include a wrapper /// type around what the user-perceived type of the parameter /// is. For example, if a parameter is declared as `out int a` /// then this function would return a type coresponding to /// `OutParam`, using the hidden `OutParam` type defined /// in the core module. /// /// Any code that calls this function should be conscious of /// the possibility of encountering these wrappers, and handle /// them accordingly. /// Type* getParamTypeWithDirectionWrapper(Index index) { return as(getOperand(index)); } /// Get the type of one of the function's parameters, by index. /// /// The type returned by this funciton is the user-perceived /// type of the parameter, and does not include any wrappers /// that are introduced to indicate the parameter-passing mode. /// For example, a parameter declared as `out int a` will simply /// return the `int` type, the same as would be returned for /// a parameter simply declared as `int a`. /// /// Any code that calls this function should be conscious of /// the possibility that the type returned may not fully /// describe the contract for the given parameter, and should /// make sure to consult `getParamDirection` as well, to get /// a complete picture. /// Type* getParamValueType(Index index); /// Get the parameter-passing mode of one of the function's parameters, by index. /// ParamPassingMode getParamDirection(Index index); /// Combined information on the type and parameter-passing mode of a parameter. /// struct ParamInfo { /// The parameter-passing mode used for the parameter. ParamPassingMode direction = ParamPassingMode::In; /// The user-perceived type of the parameter. Type* type = nullptr; }; /// Get combined information on the type and parameter-passing mode of a parameter. /// ParamInfo getParamInfo(Index index) { ParamInfo info; info.direction = getParamDirection(index); info.type = getParamValueType(index); return info; } /// Get the result type of this function. /// /// This is the type that a call to the function evaluates to if /// the function returns successfully. /// /// A function that conceptually returns no value will have the `Unit` /// type as its result type. /// /// A type that can never return will have the bottom type `Never` /// as its result type. /// Type* getResultType() { return as(getOperand(m_operands.getCount() - 2)); } /// Get the type of errors (if any) that this function can fail with. /// /// Evaluation of a call to a function with this `FuncType` may fail /// with an error of the corresponding error type. /// /// A function that cannot fail with an error will have the bottom /// type `Never` as its error type. /// /// Note that a function that "never fails" at the type system level /// may still fail in various ways that are perceivable to the user. /// The error type of a function only refers to failure modes that /// are being explicitly modeled using the Slang type system. /// Type* getErrorType() { return as(getOperand(m_operands.getCount() - 1)); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; // A tuple is a product of its member types FIDDLE() class TupleType : public DeclRefType { FIDDLE(...) Index getMemberCount() const; Type* getMember(Index i) const; Type* getTypePack() const; }; FIDDLE() class EachType : public Type { FIDDLE(...) Type* getElementType() const { return as(getOperand(0)); } DeclRefType* getElementDeclRefType() const { return as(getOperand(0)); } EachType(Type* elementType) { m_operands.add(ValNodeOperand(elementType)); } void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; FIDDLE() class ExpandType : public Type { FIDDLE(...) Type* getPatternType() const { return as(getOperand(0)); } Index getCapturedTypePackCount() { return getOperandCount() - 1; } Type* getCapturedTypePack(Index i) { return as(getOperand(i + 1)); } ExpandType(Type* patternType, ArrayView capturedPacks) { m_operands.add(ValNodeOperand(patternType)); for (auto t : capturedPacks) m_operands.add(ValNodeOperand(t)); } void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; // A concrete pack of types. FIDDLE() class ConcreteTypePack : public Type { FIDDLE(...) ConcreteTypePack(ArrayView types) { for (auto t : types) m_operands.add(ValNodeOperand(t)); } Index getTypeCount() { return getOperandCount(); } Type* getElementType(Index i) { return as(getOperand(i)); } void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; // The "type" of an expression that names a generic declaration. FIDDLE() class GenericDeclRefType : public Type { FIDDLE(...) DeclRef getDeclRef() const { return as(getOperand(0)); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); GenericDeclRefType(DeclRef declRef) { setOperands(declRef); } }; // The "type" of a reference to a module or namespace FIDDLE() class NamespaceType : public Type { FIDDLE(...) DeclRef getDeclRef() const { return as(getOperand(0)); } NamespaceType(DeclRef inDeclRef) { setOperands(inDeclRef); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); }; // The concrete type for a value wrapped in an existential, accessible // when the existential is "opened" in some context. FIDDLE() class ExtractExistentialType : public Type { FIDDLE(...) DeclRef getDeclRef() const { return as(getOperand(0)); } // A reference to the original interface this type is known // to be a subtype of. // Type* getOriginalInterfaceType() { return as(getOperand(1)); } DeclRef getOriginalInterfaceDeclRef() { return as(getOperand(2)); } ExtractExistentialType( DeclRef inDeclRef, Type* inOriginalInterfaceType, DeclRef inOriginalInterfaceDeclRef) { setOperands(inDeclRef, inOriginalInterfaceType, inOriginalInterfaceDeclRef); } // A cached decl-ref to the original interface's ThisType Decl, with // a witness that refers to the type extracted here. // // This field is optional and can be filled in on-demand. It does *not* // represent part of the logical value of this `Type`, and should not // be serialized, included in hashes, etc. // DeclRef cachedThisTypeDeclRef; // A cached pointer to a witness that shows how this type is a subtype // of `originalInterfaceType`. // SubtypeWitness* cachedSubtypeWitness = nullptr; // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); /// Get a witness that shows how this type is a subtype of `originalInterfaceType`. /// /// This operation may create the witness on demand and cache it. /// SubtypeWitness* getSubtypeWitness(); /// Get a decl-ref to the interface's ThisType decl, which represents a substitutable type /// from which lookup can be performed. /// /// This operation may create the decl-ref on demand and cache it. /// DeclRef getThisTypeDeclRef(); }; FIDDLE() class ExistentialSpecializedType : public Type { FIDDLE(...) Type* getBaseType() { return as(getOperand(0)); } ExpandedSpecializationArg getArg(Index i) { ExpandedSpecializationArg arg; arg.val = getOperand(i * 2 + 1); arg.witness = getOperand(i * 2 + 2); return arg; } Index getArgCount() { return (getOperandCount() - 1) / 2; } ExistentialSpecializedType(Type* inBaseType, ExpandedSpecializationArgs const& inArgs) { m_operands.add(ValNodeOperand(inBaseType)); for (auto arg : inArgs) { m_operands.add(ValNodeOperand(arg.val)); m_operands.add(ValNodeOperand(arg.witness)); } } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; /// The type of `this` within a polymorphic declaration FIDDLE() class ThisType : public DeclRefType { FIDDLE(...) ThisType(DeclRefBase* declRef) : DeclRefType(declRef) { } DeclRef getInterfaceDeclRef(); }; /// The type of `A & B` where `A` and `B` are types /// /// A value `v` is of type `A & B` if it is both of type `A` and of type `B`. FIDDLE() class AndType : public Type { FIDDLE(...) Type* getLeft() { return as(getOperand(0)); } Type* getRight() { return as(getOperand(1)); } AndType(Type* leftType, Type* rightType) { setOperands(leftType, rightType); } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; FIDDLE() class ModifiedType : public Type { FIDDLE(...) Type* getBase() { return as(getOperand(0)); } Index getModifierCount() { return getOperandCount() - 1; } Val* getModifier(Index index) { return getOperand(index + 1); } ModifiedType(Type* inBase, ArrayView inModifiers) { m_operands.add(ValNodeOperand(inBase)); for (auto modifier : inModifiers) m_operands.add(ValNodeOperand(modifier)); } template T* findModifier() { for (Index i = 1; i < getOperandCount(); i++) if (auto rs = as(getOperand(i))) return rs; return nullptr; } // Overrides should be public so base classes can access void _toTextOverride(StringBuilder& out); Type* _createCanonicalTypeOverride(); Val* _substituteImplOverride(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff); }; Type* removeParamDirType(Type* type); bool isNonCopyableType(Type* type); } // namespace Slang