From acd4228faaec918d3b24c131765468072fb15977 Mon Sep 17 00:00:00 2001 From: slangbot <186143334+slangbot@users.noreply.github.com> Date: Fri, 18 Apr 2025 01:46:55 +0000 Subject: [PATCH] format code --- source/slang/slang-ast-base.h | 32 +- source/slang/slang-ast-boilerplate.cpp | 14 +- source/slang/slang-ast-decl-ref.cpp | 2 +- source/slang/slang-ast-decl.h | 1 - source/slang/slang-ast-dump.cpp | 10 +- source/slang/slang-ast-expr.h | 1 - source/slang/slang-ast-forward-declarations.h | 10 +- source/slang/slang-ast-iterator.h | 5 +- source/slang/slang-ast-modifier.h | 661 +++- source/slang/slang-ast-stmt.h | 1 - source/slang/slang-ast-support-types.h | 2820 +++++++++-------- source/slang/slang-ast-type.cpp | 2 +- source/slang/slang-ast-val.cpp | 2 +- source/slang/slang-ast-val.h | 1 - source/slang/slang-check-decl.cpp | 2 +- source/slang/slang-check-resolve-val.cpp | 2 +- source/slang/slang-check-type.cpp | 5 +- source/slang/slang-compiler.cpp | 3 +- source/slang/slang-module-library.cpp | 4 +- source/slang/slang-parser.h | 4 +- source/slang/slang-serialize-ast.cpp | 1968 ++++++------ source/slang/slang-serialize-ast.h | 24 +- source/slang/slang-serialize-container.cpp | 590 ++-- source/slang/slang-serialize-container.h | 61 +- source/slang/slang-serialize-types.h | 4 +- source/slang/slang-serialize.h | 203 +- source/slang/slang-syntax.cpp | 18 +- source/slang/slang-visitor.h | 30 +- source/slang/slang.cpp | 84 +- 29 files changed, 3347 insertions(+), 3217 deletions(-) diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h index fabfc342b69..72da9cf569a 100644 --- a/source/slang/slang-ast-base.h +++ b/source/slang/slang-ast-base.h @@ -2,12 +2,11 @@ #pragma once +#include "slang-ast-base.h.fiddle" #include "slang-ast-forward-declarations.h" #include "slang-ast-support-types.h" #include "slang-capability.h" -#include "slang-ast-base.h.fiddle" - // This file defines the primary base classes for the hierarchy of // AST nodes and related objects. For example, this is where the // basic `Decl`, `Stmt`, `Expr`, `type`, etc. definitions come from. @@ -37,10 +36,7 @@ class NodeBase void _initDebug(ASTNodeType inAstNodeType, ASTBuilder* inAstBuilder); - SyntaxClass getClass() const - { - return SyntaxClass(astNodeType); - } + SyntaxClass getClass() const { return SyntaxClass(astNodeType); } /// The type of the node. ASTNodeType(-1) is an invalid node type, and shouldn't appear on any /// correctly constructed (through ASTBuilder) NodeBase derived class. @@ -57,37 +53,25 @@ class NodeBase template SLANG_FORCE_INLINE T* dynamicCast(NodeBase* node) { - return (node && - node->getClass().isSubClassOf()) - ? static_cast(node) - : nullptr; + return (node && node->getClass().isSubClassOf()) ? static_cast(node) : nullptr; } template SLANG_FORCE_INLINE const T* dynamicCast(const NodeBase* node) { - return (node && - node->getClass().isSubClassOf()) - ? static_cast(node) - : nullptr; + return (node && node->getClass().isSubClassOf()) ? static_cast(node) : nullptr; } template SLANG_FORCE_INLINE T* as(NodeBase* node) { - return (node && - node->getClass().isSubClassOf()) - ? static_cast(node) - : nullptr; + return (node && node->getClass().isSubClassOf()) ? static_cast(node) : nullptr; } template SLANG_FORCE_INLINE const T* as(const NodeBase* node) { - return (node && - node->getClass().isSubClassOf()) - ? static_cast(node) - : nullptr; + return (node && node->getClass().isSubClassOf()) ? static_cast(node) : nullptr; } // Because DeclRefBase is now a `Val`, we prevent casting it directly into other nodes @@ -746,7 +730,9 @@ struct ProvenenceNodeWithLoc // An intermediate type to represent either a single declaration, or a group of declarations FIDDLE(abstract) class DeclBase : public ModifiableSyntaxNode -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE(abstract) class Decl : public DeclBase diff --git a/source/slang/slang-ast-boilerplate.cpp b/source/slang/slang-ast-boilerplate.cpp index 2d3fd7168d8..0313d44117a 100644 --- a/source/slang/slang-ast-boilerplate.cpp +++ b/source/slang/slang-ast-boilerplate.cpp @@ -1,23 +1,17 @@ // slang-ast-boilerplate.cpp -#include "slang-ast-forward-declarations.h" #include "slang-ast-all.h" #include "slang-ast-builder.h" +#include "slang-ast-forward-declarations.h" namespace Slang { template struct Helper { - static void* create(ASTBuilder* builder) - { - return builder->createImpl(); - } + static void* create(ASTBuilder* builder) { return builder->createImpl(); } - static void destruct(void* obj) - { - ((T*)obj)->~T(); - } + static void destruct(void* obj) { ((T*)obj)->~T(); } }; #if 0 // FIDDLE TEMPLATE: @@ -57,4 +51,4 @@ SyntaxClassBase::SyntaxClassBase(ASTNodeType tag) _info = kAllSyntaxClasses[int(tag)]; } -} +} // namespace Slang diff --git a/source/slang/slang-ast-decl-ref.cpp b/source/slang/slang-ast-decl-ref.cpp index b553884bd8f..a44e5b8178e 100644 --- a/source/slang/slang-ast-decl-ref.cpp +++ b/source/slang/slang-ast-decl-ref.cpp @@ -1,9 +1,9 @@ // slang-ast-decl-ref.cpp #include "slang-ast-builder.h" +#include "slang-ast-dispatch.h" #include "slang-ast-forward-declarations.h" #include "slang-check-impl.h" -#include "slang-ast-dispatch.h" namespace Slang { diff --git a/source/slang/slang-ast-decl.h b/source/slang/slang-ast-decl.h index 1a85fe4e4f5..261d2458a82 100644 --- a/source/slang/slang-ast-decl.h +++ b/source/slang/slang-ast-decl.h @@ -3,7 +3,6 @@ #pragma once #include "slang-ast-base.h" - #include "slang-ast-decl.h.fiddle" FIDDLE() diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp index d7aa6dc2517..24b10344dbe 100644 --- a/source/slang/slang-ast-dump.cpp +++ b/source/slang/slang-ast-dump.cpp @@ -790,16 +790,11 @@ struct ASTDumpAccess static void dump(NodeBase* base, ASTDumpContext& context) { - ASTNodeDispatcher::dispatch(base, [&](auto b) - { - dump_(b, context); - }); + ASTNodeDispatcher::dispatch(base, [&](auto b) { dump_(b, context); }); } }; -void ASTDumpContext::dumpObjectReference( - NodeBase* obj, - Index objIndex) +void ASTDumpContext::dumpObjectReference(NodeBase* obj, Index objIndex) { SLANG_UNUSED(obj); ScopeWrite(this).getBuf() << obj->getClass().getName() << ":" << objIndex; @@ -858,4 +853,3 @@ void ASTDumpContext::dumpObjectFull(NodeBase* node) } } // namespace Slang - diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h index 14a9f125a53..cd5f9b6e8c8 100644 --- a/source/slang/slang-ast-expr.h +++ b/source/slang/slang-ast-expr.h @@ -2,7 +2,6 @@ #pragma once #include "slang-ast-base.h" - #include "slang-ast-expr.h.fiddle" FIDDLE() diff --git a/source/slang/slang-ast-forward-declarations.h b/source/slang/slang-ast-forward-declarations.h index f71f7cd093b..717bca1d970 100644 --- a/source/slang/slang-ast-forward-declarations.h +++ b/source/slang/slang-ast-forward-declarations.h @@ -4,8 +4,8 @@ namespace Slang { - enum class ASTNodeType - { +enum class ASTNodeType +{ #if 0 // FIDDLE TEMPLATE: %for _, T in ipairs(Slang.NodeBase.subclasses) do $T, @@ -14,8 +14,8 @@ namespace Slang #define FIDDLE_GENERATED_OUTPUT_ID 0 #include "slang-ast-forward-declarations.h.fiddle" #endif // FIDDLE END - CountOf - }; + CountOf +}; #if 0 // FIDDLE TEMPLATE: %for _, T in ipairs(Slang.NodeBase.subclasses) do @@ -26,4 +26,4 @@ namespace Slang #include "slang-ast-forward-declarations.h.fiddle" #endif // FIDDLE END -} +} // namespace Slang diff --git a/source/slang/slang-ast-iterator.h b/source/slang/slang-ast-iterator.h index dcff8a640c2..fdfb6ecef96 100644 --- a/source/slang/slang-ast-iterator.h +++ b/source/slang/slang-ast-iterator.h @@ -314,10 +314,7 @@ struct ASTIterator } } - void visitDetachExpr(DetachExpr* expr) - { - iterator->maybeDispatchCallback(expr); - } + void visitDetachExpr(DetachExpr* expr) { iterator->maybeDispatchCallback(expr); } }; struct ASTIteratorStmtVisitor : public StmtVisitor diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h index f4b7b90709f..b32639ed3c9 100644 --- a/source/slang/slang-ast-modifier.h +++ b/source/slang/slang-ast-modifier.h @@ -2,7 +2,6 @@ #pragma once #include "slang-ast-base.h" - #include "slang-ast-modifier.h.fiddle" FIDDLE() @@ -15,106 +14,156 @@ namespace Slang FIDDLE() class InModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class OutModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ConstModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class BuiltinModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class InlineModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE(abstract) class VisibilityModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PublicModifier : public VisibilityModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PrivateModifier : public VisibilityModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class InternalModifier : public VisibilityModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class RequireModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ParamModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ExternModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLExportModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class TransparentModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class FromCoreModuleModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PrefixModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PostfixModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ExportedModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ConstExprModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class ExternCppModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLPrecisionModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLModuleModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Marks that the definition of a decl is not yet synthesized. FIDDLE() class ToBeSynthesizedModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Marks that the definition of a decl is synthesized. FIDDLE() class SynthesizedModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Marks a synthesized variable as local temporary variable. FIDDLE() class LocalTempVarModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // An `extern` variable in an extension is used to introduce additional attributes on an existing // field. @@ -122,20 +171,24 @@ FIDDLE() class ExtensionExternVarModifier : public Modifier { FIDDLE(...) - FIDDLE() DeclRef originalDecl; + FIDDLE() DeclRef originalDecl; }; // An 'ActualGlobal' is a global that is output as a normal global in CPU code. // Globals in HLSL/Slang are constant state passed into kernel execution FIDDLE() class ActualGlobalModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A modifier that indicates an `InheritanceDecl` should be ignored during name lookup (and related /// checks). FIDDLE() class IgnoreForLookupModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A modifier that marks something as an operation that // has a one-to-one translation to the IR, and thus @@ -235,18 +288,24 @@ class RequiredCUDASMVersionModifier : public Modifier FIDDLE() class InOutModifier : public OutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `__ref` modifier for by-reference parameter passing FIDDLE() class RefModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `__ref` modifier for by-reference parameter passing FIDDLE() class ConstRefModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // This is a special sentinel modifier that gets added // to the list when we have multiple variable declarations @@ -264,60 +323,84 @@ class ConstRefModifier : public Modifier // FIDDLE() class SharedModifiers : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // AST nodes to represent the begin/end of a `layout` modifier group FIDDLE(abstract) class GLSLLayoutModifierGroupMarker : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLLayoutModifierGroupBegin : public GLSLLayoutModifierGroupMarker -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLLayoutModifierGroupEnd : public GLSLLayoutModifierGroupMarker -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLUnparsedLayoutModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLBufferDataLayoutModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLStd140Modifier : public GLSLBufferDataLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLStd430Modifier : public GLSLBufferDataLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLScalarModifier : public GLSLBufferDataLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A catch-all for single-keyword modifiers FIDDLE() class SimpleModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Indicates that this is a variable declaration that corresponds to // a parameter block declaration in the source program. FIDDLE() class ImplicitParameterGroupVariableModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Indicates that this is a type that corresponds to the element // type of a parameter block declaration in the source program. FIDDLE() class ImplicitParameterGroupElementTypeModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // An HLSL semantic @@ -357,7 +440,9 @@ class HLSLPackOffsetSemantic : public HLSLLayoutSemantic // An HLSL semantic that just associated a declaration with a semantic name FIDDLE() class HLSLSimpleSemantic : public HLSLSemantic -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A semantic applied to a field of a ray-payload type, to control access FIDDLE() @@ -369,11 +454,15 @@ class RayPayloadAccessSemantic : public HLSLSemantic FIDDLE() class RayPayloadReadSemantic : public RayPayloadAccessSemantic -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class RayPayloadWriteSemantic : public RayPayloadAccessSemantic -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // GLSL @@ -382,7 +471,9 @@ class RayPayloadWriteSemantic : public RayPayloadAccessSemantic // that we need to keep around for later steps FIDDLE() class GLSLPreprocessorDirective : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A GLSL `#version` directive @@ -469,26 +560,36 @@ class IntrinsicTypeModifier : public Modifier // Modifiers that affect the storage layout for matrices FIDDLE(abstract) class MatrixLayoutModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Modifiers that specify row- and column-major layout, respectively FIDDLE(abstract) class RowMajorLayoutModifier : public MatrixLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE(abstract) class ColumnMajorLayoutModifier : public MatrixLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // The HLSL flavor of those modifiers FIDDLE() class HLSLRowMajorLayoutModifier : public RowMajorLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLColumnMajorLayoutModifier : public ColumnMajorLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // The GLSL flavor of those modifiers @@ -500,91 +601,121 @@ class HLSLColumnMajorLayoutModifier : public ColumnMajorLayoutModifier // GLSL specifies them. FIDDLE() class GLSLRowMajorLayoutModifier : public ColumnMajorLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLColumnMajorLayoutModifier : public RowMajorLayoutModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // More HLSL Keyword FIDDLE(abstract) class InterpolationModeModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `nointerpolation` modifier FIDDLE() class HLSLNoInterpolationModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `noperspective` modifier FIDDLE() class HLSLNoPerspectiveModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `linear` modifier FIDDLE() class HLSLLinearModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `sample` modifier FIDDLE() class HLSLSampleModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `centroid` modifier FIDDLE() class HLSLCentroidModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// Slang-defined `pervertex` modifier FIDDLE() class PerVertexModifier : public InterpolationModeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `precise` modifier FIDDLE() class PreciseModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `shared` modifier (which is used by the effect system, // and shouldn't be confused with `groupshared`) FIDDLE() class HLSLEffectSharedModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `groupshared` modifier FIDDLE() class HLSLGroupSharedModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `static` modifier (probably doesn't need to be // treated as HLSL-specific) FIDDLE() class HLSLStaticModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `uniform` modifier (distinct meaning from GLSL // use of the keyword) FIDDLE() class HLSLUniformModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // HLSL `volatile` modifier (ignored) FIDDLE() class HLSLVolatileModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() @@ -724,7 +855,9 @@ class Attribute : public AttributeBase FIDDLE() class UserDefinedAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class AttributeUsageAttribute : public Attribute @@ -735,7 +868,9 @@ class AttributeUsageAttribute : public Attribute FIDDLE() class NonDynamicUniformAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class RequireCapabilityAttribute : public Attribute @@ -748,7 +883,9 @@ class RequireCapabilityAttribute : public Attribute // An `[unroll]` or `[unroll(count)]` attribute FIDDLE() class UnrollAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // An `[unroll]` or `[unroll(count)]` attribute FIDDLE() @@ -777,57 +914,79 @@ class InferredMaxItersAttribute : public Attribute FIDDLE() class LoopAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[loop]` FIDDLE() class FastOptAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[fastopt]` FIDDLE() class AllowUAVConditionAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[allow_uav_condition]` FIDDLE() class BranchAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[branch]` FIDDLE() class FlattenAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[flatten]` FIDDLE() class ForceCaseAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[forcecase]` FIDDLE() class CallAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[call]` FIDDLE() class UnscopedEnumAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Marks a enum to have `flags` semantics, where each enum case is a bitfield. FIDDLE() class FlagsAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_push_constant]] [[push_constant]] FIDDLE() class PushConstantAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_specialization_constant]] [[specialization_constant]] FIDDLE() class SpecializationConstantAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_constant_id]] FIDDLE() @@ -840,7 +999,9 @@ class VkConstantIdAttribute : public Attribute // [[vk_shader_record]] [[shader_record]] FIDDLE() class ShaderRecordAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_binding]] @@ -854,11 +1015,15 @@ class GLSLBindingAttribute : public Attribute FIDDLE() class VkAliasedPointerAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class VkRestrictPointerAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLOffsetLayoutAttribute : public Attribute @@ -893,28 +1058,38 @@ class GLSLInputAttachmentIndexLayoutAttribute : public Attribute // [[vk_location]] FIDDLE() class GLSLLocationAttribute : public GLSLSimpleIntegerLayoutAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_index]] FIDDLE() class GLSLIndexAttribute : public GLSLSimpleIntegerLayoutAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[vk_spirv_instruction]] FIDDLE() class SPIRVInstructionOpAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[spv_target_env_1_3]] FIDDLE() class SPIRVTargetEnv13Attribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // [[disable_array_flattening]] FIDDLE() class DisableArrayFlatteningAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A GLSL layout(local_size_x = 64, ... attribute) FIDDLE() @@ -937,30 +1112,42 @@ class GLSLLayoutLocalSizeAttribute : public Attribute FIDDLE() class GLSLLayoutDerivativeGroupQuadAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLLayoutDerivativeGroupLinearAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // TODO: for attributes that take arguments, the syntax node // classes should provide accessors for the values of those arguments. FIDDLE() class MaxTessFactorAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class OutputControlPointsAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class OutputTopologyAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PartitioningAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PatchConstantFuncAttribute : public Attribute @@ -971,12 +1158,16 @@ class PatchConstantFuncAttribute : public Attribute FIDDLE() class DomainAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class EarlyDepthStencilAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // `[earlydepthstencil]` // An HLSL `[numthreads(x,y,z)]` attribute @@ -1080,7 +1271,9 @@ class VulkanCallablePayloadInAttribute : public Attribute // intersection shader to pass hit attribute information. FIDDLE() class VulkanHitAttributesAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[__vulkanHitObjectAttributes(location)]` attribute, which is used in the // core module implementation to indicate that a variable @@ -1099,7 +1292,9 @@ class VulkanHitObjectAttributesAttribute : public Attribute // FIDDLE() class MutatingAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[nonmutating]` attribute, which indicates that a // `set` accessor does not need to modify anything through @@ -1107,21 +1302,27 @@ class MutatingAttribute : public Attribute // FIDDLE() class NonmutatingAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[constref]` attribute, which indicates that the `this` parameter of // a member function should be passed by const reference. // FIDDLE() class ConstRefAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[ref]` attribute, which indicates that the `this` parameter of // a member function should be passed by reference. // FIDDLE() class RefAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[__readNone]` attribute, which indicates that a function // computes its results strictly based on argument values, without @@ -1130,7 +1331,9 @@ class RefAttribute : public Attribute // FIDDLE() class ReadNoneAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[__GLSLRequireShaderInputParameter]` attribute to annotate @@ -1146,49 +1349,71 @@ class GLSLRequireShaderInputParameterAttribute : public Attribute // HLSL modifiers for geometry shader input topology FIDDLE() class HLSLGeometryShaderInputPrimitiveTypeModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLPointModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLLineModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLTriangleModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLLineAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLTriangleAdjModifier : public HLSLGeometryShaderInputPrimitiveTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Mesh shader paramters FIDDLE() class HLSLMeshShaderOutputModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLVerticesModifier : public HLSLMeshShaderOutputModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLIndicesModifier : public HLSLMeshShaderOutputModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLPrimitivesModifier : public HLSLMeshShaderOutputModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class HLSLPayloadModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A modifier to indicate that a constructor/initializer can be used // to perform implicit type conversion, and to specify the cost of @@ -1223,7 +1448,9 @@ class AllowAttribute : public Attribute // FIDDLE() class ExternAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // An `[__unsafeForceInlineExternal]` attribute indicates that the callee should be inlined @@ -1231,43 +1458,57 @@ class ExternAttribute : public Attribute // FIDDLE() class UnsafeForceInlineEarlyAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[ForceInline]` attribute indicates that the callee should be inlined // by the Slang compiler. // FIDDLE() class ForceInlineAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a type declaration as either allowing or /// disallowing the type to be inherited from in other modules. FIDDLE(abstract) class InheritanceControlAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a type declaration as allowing the type to be inherited from in other /// modules. FIDDLE() class OpenAttribute : public InheritanceControlAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a type declaration as disallowing the type to be inherited from in other /// modules. FIDDLE() class SealedAttribute : public InheritanceControlAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a decl as a compiler built-in object. FIDDLE() class BuiltinAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a decl as a compiler built-in object for the autodiff system. FIDDLE() class AutoDiffBuiltinAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that defines the size of `AnyValue` type to represent a polymoprhic value that /// conforms to the decorated interface type. @@ -1295,7 +1536,9 @@ class OverloadRankAttribute : public Attribute /// dynamic dispatch through the interface is a compile-time error. FIDDLE() class SpecializeAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// An attribute that marks a type, function or variable as differentiable. FIDDLE() @@ -1335,27 +1578,39 @@ class DllImportAttribute : public Attribute FIDDLE() class DllExportAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class TorchEntryPointAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class CudaDeviceExportAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class CudaKernelAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class CudaHostAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class AutoPyBindCudaAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class PyExportAttribute : public Attribute @@ -1380,7 +1635,9 @@ class PreferRecomputeAttribute : public Attribute FIDDLE() class PreferCheckpointAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class DerivativeMemberAttribute : public Attribute @@ -1401,7 +1658,9 @@ class ComInterfaceAttribute : public Attribute /// requires NVAPI operations for its implementation on D3D. FIDDLE() class RequiresNVAPIAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A `[RequirePrelude(target, "string")]` attribute indicates that the declaration being modifed /// requires a textual prelude to be injected in the resulting target code. @@ -1417,19 +1676,25 @@ class RequirePreludeAttribute : public Attribute /// function should always be folded into use sites during source emit. FIDDLE() class AlwaysFoldIntoUseSiteAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // A `[TreatAsDifferentiableAttribute]` attribute indicates that a function or an interface // should be treated as differentiable in IR validation step. // FIDDLE() class TreatAsDifferentiableAttribute : public DifferentiableAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// The `[ForwardDifferentiable]` attribute indicates that a function can be forward-differentiated. FIDDLE() class ForwardDifferentiableAttribute : public DifferentiableAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class UserDefinedDerivativeAttribute : public DifferentiableAttribute @@ -1442,7 +1707,9 @@ class UserDefinedDerivativeAttribute : public DifferentiableAttribute /// be used as the derivative for the decorated function. FIDDLE() class ForwardDerivativeAttribute : public UserDefinedDerivativeAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class DerivativeOfAttribute : public DifferentiableAttribute @@ -1450,7 +1717,8 @@ class DerivativeOfAttribute : public DifferentiableAttribute FIDDLE(...) FIDDLE() Expr* funcExpr; - FIDDLE() Expr* backDeclRef; // DeclRef to this derivative function when initiated from primalFunction. + FIDDLE() + Expr* backDeclRef; // DeclRef to this derivative function when initiated from primalFunction. }; /// The `[ForwardDerivativeOf(primalFunction)]` attribute marks the decorated function as custom @@ -1459,7 +1727,9 @@ class DerivativeOfAttribute : public DifferentiableAttribute /// function itself is considered differentiable. FIDDLE() class ForwardDerivativeOfAttribute : public DerivativeOfAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// The `[BackwardDifferentiable]` attribute indicates that a function can be /// backward-differentiated. @@ -1474,13 +1744,17 @@ class BackwardDifferentiableAttribute : public DifferentiableAttribute /// be used as the backward-derivative for the decorated function. FIDDLE() class BackwardDerivativeAttribute : public UserDefinedDerivativeAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// The `[BackwardDerivativeOf(primalFunction)]` attribute marks the decorated function as custom /// backward-derivative implementation for `primalFunction`. FIDDLE() class BackwardDerivativeOfAttribute : public DerivativeOfAttribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// The `[PrimalSubstitute(function)]` attribute specifies a custom function that should /// be used as the primal function substitute when differentiating code that calls the primal @@ -1499,14 +1773,17 @@ class PrimalSubstituteOfAttribute : public Attribute { FIDDLE(...) FIDDLE() Expr* funcExpr; - FIDDLE() Expr* backDeclRef; // DeclRef to this derivative function when initiated from primalFunction. + FIDDLE() + Expr* backDeclRef; // DeclRef to this derivative function when initiated from primalFunction. }; /// The `[NoDiffThis]` attribute is used to specify that the `this` parameter should not be /// included for differentiation. FIDDLE() class NoDiffThisAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// Indicates that the modified declaration is one of the "magic" declarations /// that NVAPI uses to communicate extended operations. When NVAPI is being included @@ -1514,7 +1791,9 @@ class NoDiffThisAttribute : public Attribute /// will not be emitted, instead allowing the versions from the prelude to be used. FIDDLE() class NVAPIMagicModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A modifier that attaches to a `ModuleDecl` to indicate the register/space binding /// that NVAPI wants to use, as indicated by, e.g., the `NV_SHADER_EXTN_SLOT` and @@ -1551,33 +1830,47 @@ class NVAPISlotModifier : public Modifier /// FIDDLE() class NoInlineAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A `[noRefInline]` attribute represents a request to not force inline a /// function specifically due to a refType parameter. FIDDLE() class NoRefInlineAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class DerivativeGroupQuadAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class DerivativeGroupLinearAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class MaximallyReconvergesAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class QuadDerivativesAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class RequireFullQuadsAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A `[payload]` attribute indicates that a `struct` type will be used as /// a ray payload for `TraceRay()` calls, and thus also as input/output @@ -1586,7 +1879,9 @@ class RequireFullQuadsAttribute : public Attribute /// FIDDLE() class PayloadAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A `[raypayload]` attribute indicates that a `struct` type will be used as /// a ray payload for `TraceRay()` calls, and thus also as input/output @@ -1613,11 +1908,15 @@ class DeprecatedAttribute : public Attribute FIDDLE() class NonCopyableTypeAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class NoSideEffectAttribute : public Attribute -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A `[KnownBuiltin("name")]` attribute allows the compiler to /// identify this declaration during compilation, despite obfuscation or @@ -1647,63 +1946,89 @@ class KnownBuiltinAttribute : public Attribute /// FIDDLE() class TypeModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A kind of syntax element which appears as a modifier in the syntax, but /// we represent as a function over type expressions FIDDLE() class WrappingTypeModifier : public TypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// A modifier that applies to a type and implies information about the /// underlying format of a resource that uses that type as its element type. /// FIDDLE() class ResourceElementFormatModifier : public TypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// HLSL `unorm` modifier FIDDLE() class UNormModifier : public ResourceElementFormatModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; /// HLSL `snorm` modifier FIDDLE() class SNormModifier : public ResourceElementFormatModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class NoDiffModifier : public TypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GloballyCoherentModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // Some GLSL-specific modifiers FIDDLE() class GLSLBufferModifier : public WrappingTypeModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLWriteOnlyModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLReadOnlyModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLVolatileModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLRestrictModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class GLSLPatchModifier : public SimpleModifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; // FIDDLE() @@ -1719,7 +2044,9 @@ class BitFieldModifier : public Modifier FIDDLE() class DynamicUniformModifier : public Modifier -{ FIDDLE(...) }; +{ + FIDDLE(...) +}; FIDDLE() class MemoryQualifierSetModifier : public Modifier diff --git a/source/slang/slang-ast-stmt.h b/source/slang/slang-ast-stmt.h index 4a29aacbceb..a1b7c274e73 100644 --- a/source/slang/slang-ast-stmt.h +++ b/source/slang/slang-ast-stmt.h @@ -2,7 +2,6 @@ #pragma once #include "slang-ast-base.h" - #include "slang-ast-stmt.h.fiddle" FIDDLE() diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 3f54480e12b..3643c47c091 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -7,6 +7,7 @@ #include "../core/slang-basic.h" #include "../core/slang-semantic-version.h" #include "slang-ast-forward-declarations.h" +#include "slang-ast-support-types.h.fiddle" #include "slang-profile.h" #include "slang-type-system-shared.h" #include "slang.h" @@ -14,1709 +15,1716 @@ #include #include -#include "slang-ast-support-types.h.fiddle" - #define SLANG_UNREFLECTED /* empty */ -FIDDLE( -hidden class RefObject; -) +FIDDLE(hidden class RefObject;) FIDDLE() namespace Slang { -#define SLANG_AST_NODE_VIRTUAL_CALL(CLASS, METHOD, ARGS) \ - return ASTNodeDispatcherMETHOD ARGS)>::dispatch(this, [&](auto _this) -> decltype(this->METHOD ARGS) { return _this->_##METHOD##Override ARGS; }); - -class Module; -class Name; -class Session; -class SyntaxVisitor; -class FuncDecl; -class Layout; - -class Parser; -class SyntaxNode; - -class Decl; -struct QualType; -class Type; -struct TypeExp; -class Val; - -class DeclRefBase; -class NodeBase; -class LookupDeclRef; -class GenericAppDeclRef; -struct CapabilitySet; - -template -T* as(NodeBase* node); - -template -const T* as(const NodeBase* node); - -void printDiagnosticArg(StringBuilder& sb, Decl* decl); -void printDiagnosticArg(StringBuilder& sb, Type* type); -void printDiagnosticArg(StringBuilder& sb, TypeExp const& type); -void printDiagnosticArg(StringBuilder& sb, QualType const& type); -void printDiagnosticArg(StringBuilder& sb, Val* val); -void printDiagnosticArg(StringBuilder& sb, DeclRefBase* declRefBase); -void printDiagnosticArg(StringBuilder& sb, ASTNodeType nodeType); -void printDiagnosticArg(StringBuilder& sb, const CapabilitySet& set); -void printDiagnosticArg(StringBuilder& sb, List& set); - -struct QualifiedDeclPath -{ - DeclRefBase* declRef; - QualifiedDeclPath() = default; - QualifiedDeclPath(DeclRefBase* declRef) - : declRef(declRef) - { - } -}; -// Prints the fully qualified decl name. -void printDiagnosticArg(StringBuilder& sb, QualifiedDeclPath path); - - -class SyntaxNode; -SourceLoc getDiagnosticPos(SyntaxNode const* syntax); -SourceLoc getDiagnosticPos(TypeExp const& typeExp); -SourceLoc getDiagnosticPos(DeclRefBase* declRef); -SourceLoc getDiagnosticPos(Decl* decl); - -typedef NodeBase* (*SyntaxParseCallback)(Parser* parser, void* userData); - -typedef unsigned int ConversionCost; -enum : ConversionCost -{ - // No conversion at all - kConversionCost_None = 0, - - kConversionCost_GenericParamUpcast = 1, - kConversionCost_UnconstraintGenericParam = 20, - kConversionCost_SizedArrayToUnsizedArray = 30, - - // Convert between matrices of different layout - kConversionCost_MatrixLayout = 5, - - // Conversion from a buffer to the type it carries needs to add a minimal - // extra cost, just so we can distinguish an overload on `ConstantBuffer` - // from one on `Foo` - kConversionCost_GetRef = 5, - kConversionCost_ImplicitDereference = 10, - kConversionCost_InRangeIntLitConversion = 23, - kConversionCost_InRangeIntLitSignedToUnsignedConversion = 32, - kConversionCost_InRangeIntLitUnsignedToSignedConversion = 81, - - kConversionCost_MutablePtrToConstPtr = 20, - - // Conversions based on explicit sub-typing relationships are the cheapest - // - // TODO(tfoley): We will eventually need a discipline for ranking - // when two up-casts are comparable. - kConversionCost_CastToInterface = 50, - - // Conversion that is lossless and keeps the "kind" of the value the same - kConversionCost_BoolToInt = - 120, // Converting bool to int has lower cost than other integer types to prevent ambiguity. - kConversionCost_RankPromotion = 150, - kConversionCost_NoneToOptional = 150, - kConversionCost_ValToOptional = 150, - kConversionCost_NullPtrToPtr = 150, - kConversionCost_PtrToVoidPtr = 150, - - // Conversions that are lossless, but change "kind" - kConversionCost_UnsignedToSignedPromotion = 200, - - // Same-size size unsigned->signed conversions are potentially lossy, but they are commonly - // allowed silently. - kConversionCost_SameSizeUnsignedToSignedConversion = 300, +#define SLANG_AST_NODE_VIRTUAL_CALL(CLASS, METHOD, ARGS) \ + return ASTNodeDispatcherMETHOD ARGS)>::dispatch( \ + this, \ + [&](auto _this) -> decltype(this->METHOD ARGS) \ + { return _this->_##METHOD##Override ARGS; }); + + class Module; + class Name; + class Session; + class SyntaxVisitor; + class FuncDecl; + class Layout; + + class Parser; + class SyntaxNode; + + class Decl; + struct QualType; + class Type; + struct TypeExp; + class Val; + + class DeclRefBase; + class NodeBase; + class LookupDeclRef; + class GenericAppDeclRef; + struct CapabilitySet; - // Conversion from signed->unsigned integer of same or greater size - kConversionCost_SignedToUnsignedConversion = 250, - - // Cost of converting an integer to a floating-point type - kConversionCost_IntegerToFloatConversion = 400, - - // Cost of converting a pointer to bool - kConversionCost_PtrToBool = 400, - - // Cost of converting an integer to int16_t - kConversionCost_IntegerTruncate = 450, + template + T* as(NodeBase * node); - // Cost of converting an integer to a half type - kConversionCost_IntegerToHalfConversion = 500, + template + const T* as(const NodeBase* node); + + void printDiagnosticArg(StringBuilder & sb, Decl * decl); + void printDiagnosticArg(StringBuilder & sb, Type * type); + void printDiagnosticArg(StringBuilder & sb, TypeExp const& type); + void printDiagnosticArg(StringBuilder & sb, QualType const& type); + void printDiagnosticArg(StringBuilder & sb, Val * val); + void printDiagnosticArg(StringBuilder & sb, DeclRefBase * declRefBase); + void printDiagnosticArg(StringBuilder & sb, ASTNodeType nodeType); + void printDiagnosticArg(StringBuilder & sb, const CapabilitySet& set); + void printDiagnosticArg(StringBuilder & sb, List & set); + + struct QualifiedDeclPath + { + DeclRefBase* declRef; + QualifiedDeclPath() = default; + QualifiedDeclPath(DeclRefBase* declRef) + : declRef(declRef) + { + } + }; + // Prints the fully qualified decl name. + void printDiagnosticArg(StringBuilder & sb, QualifiedDeclPath path); - // Cost of using a concrete argument pack - kConversionCost_ParameterPack = 500, - // Default case (usable for user-defined conversions) - kConversionCost_Default = 500, + class SyntaxNode; + SourceLoc getDiagnosticPos(SyntaxNode const* syntax); + SourceLoc getDiagnosticPos(TypeExp const& typeExp); + SourceLoc getDiagnosticPos(DeclRefBase * declRef); + SourceLoc getDiagnosticPos(Decl * decl); + + typedef NodeBase* (*SyntaxParseCallback)(Parser* parser, void* userData); + + typedef unsigned int ConversionCost; + enum : ConversionCost + { + // No conversion at all + kConversionCost_None = 0, + + kConversionCost_GenericParamUpcast = 1, + kConversionCost_UnconstraintGenericParam = 20, + kConversionCost_SizedArrayToUnsizedArray = 30, + + // Convert between matrices of different layout + kConversionCost_MatrixLayout = 5, + + // Conversion from a buffer to the type it carries needs to add a minimal + // extra cost, just so we can distinguish an overload on `ConstantBuffer` + // from one on `Foo` + kConversionCost_GetRef = 5, + kConversionCost_ImplicitDereference = 10, + kConversionCost_InRangeIntLitConversion = 23, + kConversionCost_InRangeIntLitSignedToUnsignedConversion = 32, + kConversionCost_InRangeIntLitUnsignedToSignedConversion = 81, + + kConversionCost_MutablePtrToConstPtr = 20, + + // Conversions based on explicit sub-typing relationships are the cheapest + // + // TODO(tfoley): We will eventually need a discipline for ranking + // when two up-casts are comparable. + kConversionCost_CastToInterface = 50, + + // Conversion that is lossless and keeps the "kind" of the value the same + kConversionCost_BoolToInt = 120, // Converting bool to int has lower cost than other integer + // types to prevent ambiguity. + kConversionCost_RankPromotion = 150, + kConversionCost_NoneToOptional = 150, + kConversionCost_ValToOptional = 150, + kConversionCost_NullPtrToPtr = 150, + kConversionCost_PtrToVoidPtr = 150, + + // Conversions that are lossless, but change "kind" + kConversionCost_UnsignedToSignedPromotion = 200, + + // Same-size size unsigned->signed conversions are potentially lossy, but they are commonly + // allowed silently. + kConversionCost_SameSizeUnsignedToSignedConversion = 300, + + // Conversion from signed->unsigned integer of same or greater size + kConversionCost_SignedToUnsignedConversion = 250, + + // Cost of converting an integer to a floating-point type + kConversionCost_IntegerToFloatConversion = 400, + + // Cost of converting a pointer to bool + kConversionCost_PtrToBool = 400, + + // Cost of converting an integer to int16_t + kConversionCost_IntegerTruncate = 450, + + // Cost of converting an integer to a half type + kConversionCost_IntegerToHalfConversion = 500, + + // Cost of using a concrete argument pack + kConversionCost_ParameterPack = 500, + + // Default case (usable for user-defined conversions) + kConversionCost_Default = 500, + + // Catch-all for conversions that should be discouraged + // (i.e., that really shouldn't be made implicitly) + // + // TODO: make these conversions not be allowed implicitly in "Slang mode" + kConversionCost_GeneralConversion = 900, + + // This is the cost of an explicit conversion, which should + // not actually be performed. + kConversionCost_Explicit = 90000, + + // Additional conversion cost to add when promoting from a scalar to + // a vector (this will be added to the cost, if any, of converting + // the element type of the vector) + kConversionCost_OneVectorToScalar = 1, + kConversionCost_ScalarToVector = 2, + kConversionCost_ScalarToMatrix = 10, + kConversionCost_ScalarIntegerToFloatMatrix = + kConversionCost_IntegerToFloatConversion + kConversionCost_ScalarToMatrix, + + // Additional conversion cost to add when promoting from a scalar to + // a CoopVector (this will be added to the cost, if any, of converting + // the element type of the CoopVector) + kConversionCost_ScalarToCoopVector = 1, + + // Additional cost when casting an LValue. + kConversionCost_LValueCast = 800, + + // The cost of this conversion is defined by the type coercion constraint. + kConversionCost_TypeCoercionConstraint = 1000, + kConversionCost_TypeCoercionConstraintPlusScalarToVector = + kConversionCost_TypeCoercionConstraint + kConversionCost_ScalarToVector, + + // Conversion is impossible + kConversionCost_Impossible = 0xFFFFFFFF, + }; - // Catch-all for conversions that should be discouraged - // (i.e., that really shouldn't be made implicitly) - // - // TODO: make these conversions not be allowed implicitly in "Slang mode" - kConversionCost_GeneralConversion = 900, - - // This is the cost of an explicit conversion, which should - // not actually be performed. - kConversionCost_Explicit = 90000, - - // Additional conversion cost to add when promoting from a scalar to - // a vector (this will be added to the cost, if any, of converting - // the element type of the vector) - kConversionCost_OneVectorToScalar = 1, - kConversionCost_ScalarToVector = 2, - kConversionCost_ScalarToMatrix = 10, - kConversionCost_ScalarIntegerToFloatMatrix = - kConversionCost_IntegerToFloatConversion + kConversionCost_ScalarToMatrix, - - // Additional conversion cost to add when promoting from a scalar to - // a CoopVector (this will be added to the cost, if any, of converting - // the element type of the CoopVector) - kConversionCost_ScalarToCoopVector = 1, - - // Additional cost when casting an LValue. - kConversionCost_LValueCast = 800, - - // The cost of this conversion is defined by the type coercion constraint. - kConversionCost_TypeCoercionConstraint = 1000, - kConversionCost_TypeCoercionConstraintPlusScalarToVector = - kConversionCost_TypeCoercionConstraint + kConversionCost_ScalarToVector, - - // Conversion is impossible - kConversionCost_Impossible = 0xFFFFFFFF, -}; - -typedef unsigned int BuiltinConversionKind; -enum : BuiltinConversionKind -{ - kBuiltinConversion_Unknown = 0, - kBuiltinConversion_FloatToDouble = 1, -}; + typedef unsigned int BuiltinConversionKind; + enum : BuiltinConversionKind + { + kBuiltinConversion_Unknown = 0, + kBuiltinConversion_FloatToDouble = 1, + }; -enum class ImageFormat -{ + enum class ImageFormat + { #define SLANG_FORMAT(NAME, OTHER) NAME, #include "slang-image-format-defs.h" #undef SLANG_FORMAT -}; - -struct ImageFormatInfo -{ - SlangScalarType scalarType; ///< If image format is not made up of channels of set sizes this - ///< will be SLANG_SCALAR_TYPE_NONE - uint8_t channelCount; ///< The number of channels - uint8_t sizeInBytes; ///< Size in bytes - UnownedStringSlice name; ///< The name associated with this type. NOTE! Currently these names - ///< *are* the GLSL format names. -}; - -const ImageFormatInfo& getImageFormatInfo(ImageFormat format); - -bool findImageFormatByName(const UnownedStringSlice& name, ImageFormat* outFormat); -bool findVkImageFormatByName(const UnownedStringSlice& name, ImageFormat* outFormat); - -char const* getGLSLNameForImageFormat(ImageFormat format); - -// TODO(tfoley): We should ditch this enumeration -// and just use the IR opcodes that represent these -// types directly. The one major complication there -// is that the order of the enum values currently -// matters, since it determines promotion rank. -// We either need to keep that restriction, or -// look up promotion rank by some other means. -// - -class Decl; -class Val; - -// Helper type for pairing up a name and the location where it appeared -struct NameLoc -{ - Name* name; - SourceLoc loc; + }; - NameLoc() - : name(nullptr) + struct ImageFormatInfo { - } + SlangScalarType scalarType; ///< If image format is not made up of channels of set sizes + ///< this will be SLANG_SCALAR_TYPE_NONE + uint8_t channelCount; ///< The number of channels + uint8_t sizeInBytes; ///< Size in bytes + UnownedStringSlice name; ///< The name associated with this type. NOTE! Currently these + ///< names *are* the GLSL format names. + }; - explicit NameLoc(Name* inName) - : name(inName) - { - } + const ImageFormatInfo& getImageFormatInfo(ImageFormat format); + bool findImageFormatByName(const UnownedStringSlice& name, ImageFormat* outFormat); + bool findVkImageFormatByName(const UnownedStringSlice& name, ImageFormat* outFormat); - NameLoc(Name* inName, SourceLoc inLoc) - : name(inName), loc(inLoc) - { - } + char const* getGLSLNameForImageFormat(ImageFormat format); - NameLoc(Token const& token) - : name(token.getNameOrNull()), loc(token.getLoc()) - { - } -}; + // TODO(tfoley): We should ditch this enumeration + // and just use the IR opcodes that represent these + // types directly. The one major complication there + // is that the order of the enum values currently + // matters, since it determines promotion rank. + // We either need to keep that restriction, or + // look up promotion rank by some other means. + // -struct StringSliceLoc -{ - UnownedStringSlice name; - SourceLoc loc; + class Decl; + class Val; - StringSliceLoc() - : name(nullptr) - { - } - explicit StringSliceLoc(const UnownedStringSlice& inName) - : name(inName) - { - } - StringSliceLoc(const UnownedStringSlice& inName, SourceLoc inLoc) - : name(inName), loc(inLoc) - { - } - StringSliceLoc(Token const& token) - : loc(token.getLoc()) + // Helper type for pairing up a name and the location where it appeared + struct NameLoc { - Name* tokenName = token.getNameOrNull(); - if (tokenName) + Name* name; + SourceLoc loc; + + NameLoc() + : name(nullptr) { - name = tokenName->text.getUnownedSlice(); } - } -}; - -// Helper class for iterating over a list of heap-allocated modifiers -struct ModifierList -{ - struct Iterator - { - Modifier* current = nullptr; - Modifier* operator*() { return current; } - - void operator++(); + explicit NameLoc(Name* inName) + : name(inName) + { + } - bool operator!=(Iterator other) { return current != other.current; }; - Iterator() - : current(nullptr) + NameLoc(Name* inName, SourceLoc inLoc) + : name(inName), loc(inLoc) { } - Iterator(Modifier* modifier) - : current(modifier) + NameLoc(Token const& token) + : name(token.getNameOrNull()), loc(token.getLoc()) { } }; - ModifierList() - : modifiers(nullptr) + struct StringSliceLoc { - } + UnownedStringSlice name; + SourceLoc loc; - ModifierList(Modifier* modifiers) - : modifiers(modifiers) - { - } + StringSliceLoc() + : name(nullptr) + { + } + explicit StringSliceLoc(const UnownedStringSlice& inName) + : name(inName) + { + } + StringSliceLoc(const UnownedStringSlice& inName, SourceLoc inLoc) + : name(inName), loc(inLoc) + { + } + StringSliceLoc(Token const& token) + : loc(token.getLoc()) + { + Name* tokenName = token.getNameOrNull(); + if (tokenName) + { + name = tokenName->text.getUnownedSlice(); + } + } + }; - Iterator begin() { return Iterator(modifiers); } - Iterator end() { return Iterator(nullptr); } + // Helper class for iterating over a list of heap-allocated modifiers + struct ModifierList + { + struct Iterator + { + Modifier* current = nullptr; - Modifier* modifiers = nullptr; -}; + Modifier* operator*() { return current; } -// Helper class for iterating over heap-allocated modifiers -// of a specific type. -template -struct FilteredModifierList -{ - struct Iterator - { - Modifier* current = nullptr; + void operator++(); - T* operator*() { return (T*)current; } + bool operator!=(Iterator other) { return current != other.current; }; - void operator++(); + Iterator() + : current(nullptr) + { + } - bool operator!=(Iterator other) { return current != other.current; }; + Iterator(Modifier* modifier) + : current(modifier) + { + } + }; - Iterator() - : current(nullptr) + ModifierList() + : modifiers(nullptr) { } - Iterator(Modifier* modifier) - : current(modifier) + ModifierList(Modifier* modifiers) + : modifiers(modifiers) { } + + Iterator begin() { return Iterator(modifiers); } + Iterator end() { return Iterator(nullptr); } + + Modifier* modifiers = nullptr; }; - FilteredModifierList() - : modifiers(nullptr) + // Helper class for iterating over heap-allocated modifiers + // of a specific type. + template + struct FilteredModifierList { - } + struct Iterator + { + Modifier* current = nullptr; - FilteredModifierList(Modifier* modifiers) - : modifiers(adjust(modifiers)) - { - } + T* operator*() { return (T*)current; } - Iterator begin() { return Iterator(modifiers); } - Iterator end() { return Iterator(nullptr); } + void operator++(); - static Modifier* adjust(Modifier* modifier); + bool operator!=(Iterator other) { return current != other.current; }; - Modifier* modifiers = nullptr; -}; + Iterator() + : current(nullptr) + { + } -// A set of modifiers attached to a syntax node -struct Modifiers -{ - // The first modifier in the linked list of heap-allocated modifiers - Modifier* first = nullptr; + Iterator(Modifier* modifier) + : current(modifier) + { + } + }; - template - FilteredModifierList getModifiersOfType() - { - return FilteredModifierList(first); - } + FilteredModifierList() + : modifiers(nullptr) + { + } - // Find the first modifier of a given type, or return `nullptr` if none is found. - template - T* findModifier() - { - return *getModifiersOfType().begin(); - } + FilteredModifierList(Modifier* modifiers) + : modifiers(adjust(modifiers)) + { + } - template - bool hasModifier() - { - return findModifier() != nullptr; - } + Iterator begin() { return Iterator(modifiers); } + Iterator end() { return Iterator(nullptr); } - /// True if has no modifiers - bool isEmpty() const { return first == nullptr; } + static Modifier* adjust(Modifier* modifier); - FilteredModifierList::Iterator begin() - { - return FilteredModifierList::Iterator(first); - } - FilteredModifierList::Iterator end() - { - return FilteredModifierList::Iterator(nullptr); - } -}; + Modifier* modifiers = nullptr; + }; -class NamedExpressionType; -class GenericDecl; -class ContainerDecl; + // A set of modifiers attached to a syntax node + struct Modifiers + { + // The first modifier in the linked list of heap-allocated modifiers + Modifier* first = nullptr; -// Try to extract a simple integer value from an `IntVal`. -// This fill assert-fail if the object doesn't represent a literal value. -IntegerLiteralValue getIntVal(IntVal* val); + template + FilteredModifierList getModifiersOfType() + { + return FilteredModifierList(first); + } -/// Represents how much checking has been applied to a declaration. -enum class DeclCheckState : uint8_t -{ - /// The declaration has been parsed, but - /// is otherwise completely unchecked. - /// - Unchecked, + // Find the first modifier of a given type, or return `nullptr` if none is found. + template + T* findModifier() + { + return *getModifiersOfType().begin(); + } - /// The declaration is parsed and inserted into the initial scope, - /// ready for future lookups from within the parser for disambiguation purposes. - ReadyForParserLookup, + template + bool hasModifier() + { + return findModifier() != nullptr; + } - /// Basic checks on the modifiers of the declaration have been applied. - /// - /// For example, when a declaration has attributes, the transformation - /// of an attribute from the parsed-but-unchecked form into a checked - /// form (in which it has the appropriate C++ subclass) happens here. - /// - ModifiersChecked, + /// True if has no modifiers + bool isEmpty() const { return first == nullptr; } - /// Wiring up scopes of namespaces with their siblings defined in different - /// files/modules, and other namespaces imported via `using`. - ScopesWired, + FilteredModifierList::Iterator begin() + { + return FilteredModifierList::Iterator(first); + } + FilteredModifierList::Iterator end() + { + return FilteredModifierList::Iterator(nullptr); + } + }; - /// The type/signature of the declaration has been checked. - /// - /// For a value declaration like a variable or function, this means that - /// the type of the declaration can be queried. - /// - /// For a type declaration like a `struct` or `typedef` this means - /// that a `Type` referring to that declaration can be formed. - /// - SignatureChecked, + class NamedExpressionType; + class GenericDecl; + class ContainerDecl; - /// The declaration's basic signature has been checked to the point that - /// it is ready to be referenced in other places. - /// - /// For a function, this means that it has been organized into a - /// "redeclration group" if there are multiple functions with the - /// same name in a scope. - /// - ReadyForReference, + // Try to extract a simple integer value from an `IntVal`. + // This fill assert-fail if the object doesn't represent a literal value. + IntegerLiteralValue getIntVal(IntVal * val); - /// The declaration is ready for lookup operations to be performed. - /// - /// For type declarations (e.g., aggregate types, generic type parameters) - /// this means that any base type or constraint clauses have been - /// sufficiently checked so that we can enumerate the inheritance - /// hierarchy of the type and discover all its members. - /// - ReadyForLookup, + /// Represents how much checking has been applied to a declaration. + enum class DeclCheckState : uint8_t + { + /// The declaration has been parsed, but + /// is otherwise completely unchecked. + /// + Unchecked, - /// Any conformance declared on the declaration have been validated. - /// - /// In particular, this step means that a "witness table" has been - /// created to show how a type satisfies the requirements of any - /// interfaces it conforms to. - /// - ReadyForConformances, + /// The declaration is parsed and inserted into the initial scope, + /// ready for future lookups from within the parser for disambiguation purposes. + ReadyForParserLookup, - /// Any DeclRefTypes with substitutions have been fully resolved - /// to concrete type. E.g. `T.X` with `T=A` should resolve to `A.X`. - /// We need a separate pass to resolve these types because `A.X` - /// maybe synthesized and made available only after conformance checking. - TypesFullyResolved, + /// Basic checks on the modifiers of the declaration have been applied. + /// + /// For example, when a declaration has attributes, the transformation + /// of an attribute from the parsed-but-unchecked form into a checked + /// form (in which it has the appropriate C++ subclass) happens here. + /// + ModifiersChecked, - /// All attributes are fully checked. This is the final step before - /// checking the function body. - AttributesChecked, + /// Wiring up scopes of namespaces with their siblings defined in different + /// files/modules, and other namespaces imported via `using`. + ScopesWired, - /// The body/definition is checked. - /// - /// This step includes any validation of the declaration that is - /// immaterial to clients code using the declaration, but that is - /// nonetheless relevant to checking correctness. - /// - /// The canonical example here is checking the body of functions. - /// Client code cannot depend on *how* a function is implemented, - /// but we still need to (eventually) check the bodies of all - /// functions, so it belongs in the last phase of checking. - /// - DefinitionChecked, - DefaultConstructorReadyForUse = DefinitionChecked, + /// The type/signature of the declaration has been checked. + /// + /// For a value declaration like a variable or function, this means that + /// the type of the declaration can be queried. + /// + /// For a type declaration like a `struct` or `typedef` this means + /// that a `Type` referring to that declaration can be formed. + /// + SignatureChecked, - /// The capabilities required by the decl is infered and validated. - /// - CapabilityChecked, + /// The declaration's basic signature has been checked to the point that + /// it is ready to be referenced in other places. + /// + /// For a function, this means that it has been organized into a + /// "redeclration group" if there are multiple functions with the + /// same name in a scope. + /// + ReadyForReference, - // For convenience at sites that call `ensureDecl()`, we define - // some aliases for the above states that are expressed in terms - // of what client code needs to be able to do with a declaration. - // - // These aliases can be changed over time if we decide to add - // more phases to semantic checking. - - CanEnumerateBases = ReadyForLookup, - CanUseBaseOfInheritanceDecl = ReadyForLookup, - CanUseTypeOfValueDecl = ReadyForReference, - CanUseExtensionTargetType = ReadyForLookup, - CanUseAsType = ReadyForReference, - CanUseFuncSignature = ReadyForReference, - CanSpecializeGeneric = ReadyForReference, - CanReadInterfaceRequirements = ReadyForLookup, -}; - -/// A `DeclCheckState` plus a bit to track whether a declaration is currently being checked. -struct DeclCheckStateExt -{ - typedef uint8_t RawType; - DeclCheckStateExt() {} - DeclCheckStateExt(DeclCheckState state) - : m_raw(uint8_t(state)) - { - } + /// The declaration is ready for lookup operations to be performed. + /// + /// For type declarations (e.g., aggregate types, generic type parameters) + /// this means that any base type or constraint clauses have been + /// sufficiently checked so that we can enumerate the inheritance + /// hierarchy of the type and discover all its members. + /// + ReadyForLookup, - enum : RawType - { - /// A flag to indicate that a declaration is being checked. + /// Any conformance declared on the declaration have been validated. /// - /// The value of this flag is chosen so that it can be - /// represented in the bits of a `DeclCheckState` without - /// colliding with the bits that represent actual states. + /// In particular, this step means that a "witness table" has been + /// created to show how a type satisfies the requirements of any + /// interfaces it conforms to. /// - kBeingCheckedBit = 0x80, - }; + ReadyForConformances, + + /// Any DeclRefTypes with substitutions have been fully resolved + /// to concrete type. E.g. `T.X` with `T=A` should resolve to `A.X`. + /// We need a separate pass to resolve these types because `A.X` + /// maybe synthesized and made available only after conformance checking. + TypesFullyResolved, - DeclCheckState getState() const { return DeclCheckState(m_raw & ~kBeingCheckedBit); } - void setState(DeclCheckState state) { m_raw = (m_raw & kBeingCheckedBit) | RawType(state); } + /// All attributes are fully checked. This is the final step before + /// checking the function body. + AttributesChecked, + + /// The body/definition is checked. + /// + /// This step includes any validation of the declaration that is + /// immaterial to clients code using the declaration, but that is + /// nonetheless relevant to checking correctness. + /// + /// The canonical example here is checking the body of functions. + /// Client code cannot depend on *how* a function is implemented, + /// but we still need to (eventually) check the bodies of all + /// functions, so it belongs in the last phase of checking. + /// + DefinitionChecked, + DefaultConstructorReadyForUse = DefinitionChecked, - bool isBeingChecked() const { return (m_raw & kBeingCheckedBit) != 0; } + /// The capabilities required by the decl is infered and validated. + /// + CapabilityChecked, + + // For convenience at sites that call `ensureDecl()`, we define + // some aliases for the above states that are expressed in terms + // of what client code needs to be able to do with a declaration. + // + // These aliases can be changed over time if we decide to add + // more phases to semantic checking. + + CanEnumerateBases = ReadyForLookup, + CanUseBaseOfInheritanceDecl = ReadyForLookup, + CanUseTypeOfValueDecl = ReadyForReference, + CanUseExtensionTargetType = ReadyForLookup, + CanUseAsType = ReadyForReference, + CanUseFuncSignature = ReadyForReference, + CanSpecializeGeneric = ReadyForReference, + CanReadInterfaceRequirements = ReadyForLookup, + }; - void setIsBeingChecked(bool isBeingChecked) + /// A `DeclCheckState` plus a bit to track whether a declaration is currently being checked. + struct DeclCheckStateExt { - m_raw = (m_raw & ~kBeingCheckedBit) | (isBeingChecked ? kBeingCheckedBit : 0); - } + typedef uint8_t RawType; + DeclCheckStateExt() {} + DeclCheckStateExt(DeclCheckState state) + : m_raw(uint8_t(state)) + { + } + + enum : RawType + { + /// A flag to indicate that a declaration is being checked. + /// + /// The value of this flag is chosen so that it can be + /// represented in the bits of a `DeclCheckState` without + /// colliding with the bits that represent actual states. + /// + kBeingCheckedBit = 0x80, + }; - bool operator>=(DeclCheckState state) const { return getState() >= state; } + DeclCheckState getState() const { return DeclCheckState(m_raw & ~kBeingCheckedBit); } + void setState(DeclCheckState state) { m_raw = (m_raw & kBeingCheckedBit) | RawType(state); } - RawType getRaw() const { return m_raw; } - void setRaw(RawType raw) { m_raw = raw; } + bool isBeingChecked() const { return (m_raw & kBeingCheckedBit) != 0; } - // TODO(JS): - // Unfortunately for automatic serialization to see this member, it has to be public. - // private: - RawType m_raw = 0; -}; + void setIsBeingChecked(bool isBeingChecked) + { + m_raw = (m_raw & ~kBeingCheckedBit) | (isBeingChecked ? kBeingCheckedBit : 0); + } -void addModifier(ModifiableSyntaxNode* syntax, Modifier* modifier); + bool operator>=(DeclCheckState state) const { return getState() >= state; } -void removeModifier(ModifiableSyntaxNode* syntax, Modifier* modifier); + RawType getRaw() const { return m_raw; } + void setRaw(RawType raw) { m_raw = raw; } -FIDDLE() -struct QualType -{ - FIDDLE(...) - Type* type = nullptr; - bool isLeftValue = false; - bool hasReadOnlyOnTarget = false; - bool isWriteOnly = false; + // TODO(JS): + // Unfortunately for automatic serialization to see this member, it has to be public. + // private: + RawType m_raw = 0; + }; - QualType() = default; + void addModifier(ModifiableSyntaxNode * syntax, Modifier * modifier); - QualType(Type* type); + void removeModifier(ModifiableSyntaxNode * syntax, Modifier * modifier); - QualType(Type* type, bool isLVal) - : QualType(type) + FIDDLE() + struct QualType { - isLeftValue = isLVal; - } + FIDDLE(...) + Type* type = nullptr; + bool isLeftValue = false; + bool hasReadOnlyOnTarget = false; + bool isWriteOnly = false; + QualType() = default; - Type* Ptr() { return type; } + QualType(Type* type); - operator Type*() { return type; } - Type* operator->() { return type; } -}; + QualType(Type* type, bool isLVal) + : QualType(type) + { + isLeftValue = isLVal; + } -class ASTBuilder; -struct SyntaxClassBase; -typedef SyntaxClassBase ReflectClassInfo; -typedef SyntaxClassBase ASTClassInfo; + Type* Ptr() { return type; } -struct SyntaxClassInfo -{ -public: - char const* name; - ASTNodeType firstTag; - Count tagCount; - void* (*createFunc)(ASTBuilder*); - void (*destructFunc)(void*); + operator Type*() { return type; } + Type* operator->() { return type; } + }; - template - static SyntaxClassInfo* get() - { - return const_cast(&T::kSyntaxClassInfo); - } + class ASTBuilder; -}; + struct SyntaxClassBase; + typedef SyntaxClassBase ReflectClassInfo; + typedef SyntaxClassBase ASTClassInfo; -// A reference to a class of syntax node, that can be -// used to create instances on the fly -struct SyntaxClassBase -{ - SyntaxClassBase() - {} + struct SyntaxClassInfo + { + public: + char const* name; + ASTNodeType firstTag; + Count tagCount; + void* (*createFunc)(ASTBuilder*); + void (*destructFunc)(void*); - explicit SyntaxClassBase( - ASTNodeType tag); + template + static SyntaxClassInfo* get() + { + return const_cast(&T::kSyntaxClassInfo); + } + }; - SyntaxClassBase( - SyntaxClassInfo const* info) - : _info(info) - {} + // A reference to a class of syntax node, that can be + // used to create instances on the fly + struct SyntaxClassBase + { + SyntaxClassBase() {} + explicit SyntaxClassBase(ASTNodeType tag); - ASTNodeType getTag() const { return getInfo()->firstTag; } - UnownedTerminatedStringSlice getName() const; + SyntaxClassBase(SyntaxClassInfo const* info) + : _info(info) + { + } - void* createInstanceImpl(ASTBuilder* astBuilder) const; - void destructInstanceImpl(void* instance) const; - bool isSubClassOf(SyntaxClassBase const& super) const; + ASTNodeType getTag() const { return getInfo()->firstTag; } + UnownedTerminatedStringSlice getName() const; - typedef SyntaxClassInfo Info; + void* createInstanceImpl(ASTBuilder* astBuilder) const; + void destructInstanceImpl(void* instance) const; - Info* getInfo() const { return const_cast(_info); } - operator Info* () const { return const_cast(_info); } + bool isSubClassOf(SyntaxClassBase const& super) const; + typedef SyntaxClassInfo Info; - bool operator==(SyntaxClassBase const& other) const - { - return _info == other._info; - } + Info* getInfo() const { return const_cast(_info); } + operator Info*() const { return const_cast(_info); } - bool operator!=(SyntaxClassBase const& other) const - { - return _info != other._info; - } -private: - Info const* _info = nullptr; -}; + bool operator==(SyntaxClassBase const& other) const { return _info == other._info; } -template -struct SyntaxClass : SyntaxClassBase -{ - SyntaxClass() {} + bool operator!=(SyntaxClassBase const& other) const { return _info != other._info; } - template - SyntaxClass( - SyntaxClass const& other, - typename EnableIf::Value, void>::type* = 0) - : SyntaxClassBase(other) + private: + Info const* _info = nullptr; + }; + + template + struct SyntaxClass : SyntaxClassBase { - } + SyntaxClass() {} - explicit SyntaxClass( - SyntaxClassBase const& other) - : SyntaxClassBase(other) - {} + template + SyntaxClass( + SyntaxClass const& other, + typename EnableIf::Value, void>::type* = 0) + : SyntaxClassBase(other) + { + } - explicit SyntaxClass( - ASTNodeType tag) - : SyntaxClassBase(tag) - {} + explicit SyntaxClass(SyntaxClassBase const& other) + : SyntaxClassBase(other) + { + } - explicit SyntaxClass( - SyntaxClassInfo const* info) - : SyntaxClassBase(info) - {} + explicit SyntaxClass(ASTNodeType tag) + : SyntaxClassBase(tag) + { + } - T* createInstance(ASTBuilder* astBuilder) const { return (T*)createInstanceImpl(astBuilder); } - void destructInstance(T* instance) { destructInstanceImpl(instance); } + explicit SyntaxClass(SyntaxClassInfo const* info) + : SyntaxClassBase(info) + { + } - bool isSubClassOf(SyntaxClassBase const& other) - { - return SyntaxClassBase::isSubClassOf(other); - } + T* createInstance(ASTBuilder* astBuilder) const + { + return (T*)createInstanceImpl(astBuilder); + } + void destructInstance(T* instance) { destructInstanceImpl(instance); } - template - bool isSubClassOf() - { - return SyntaxClassBase::isSubClassOf(getSyntaxClass()); - } -}; + bool isSubClassOf(SyntaxClassBase const& other) + { + return SyntaxClassBase::isSubClassOf(other); + } -template -SyntaxClass getSyntaxClass() -{ - return SyntaxClass(SyntaxClassInfo::get()); -} + template + bool isSubClassOf() + { + return SyntaxClassBase::isSubClassOf(getSyntaxClass()); + } + }; -struct SubstitutionSet -{ - DeclRefBase* declRef = nullptr; - - // The element index if the substitution is happening inside a pack expansion. - // For example, if we are substituting the pattern type of `expand each T`, where - // `T` is a type pack, then packExpansionIndex will have a value starting from 0 - // to the count of the type pack during expansion of the `expand` type when we - // substitute `each T` with the element of `T` at index `packExpansionIndex`. - int packExpansionIndex = -1; - - SubstitutionSet() = default; - SubstitutionSet(DeclRefBase* declRefBase) - : declRef(declRefBase) + template + SyntaxClass getSyntaxClass() { + return SyntaxClass(SyntaxClassInfo::get()); } - explicit operator bool() const; - - template - void forEachGenericSubstitution(F func) const; - - template - void forEachSubstitutionArg(F func) const; - - Type* applyToType(ASTBuilder* astBuilder, Type* type) const; - DeclRefBase* applyToDeclRef(ASTBuilder* astBuilder, DeclRefBase* declRef) const; - - LookupDeclRef* findLookupDeclRef() const; - GenericAppDeclRef* findGenericAppDeclRef(GenericDecl* genericDecl) const; - GenericAppDeclRef* findGenericAppDeclRef() const; - DeclRefBase* getInnerMostNodeWithSubstInfo() const; -}; - -/// An expression together with (optional) substutions to apply to it -/// -/// Under the hood this is a pair of an `Expr*` and a `SubstitutionSet`. -/// Conceptually it represents the result of applying the substitutions, -/// recursively, to the given expression. -/// -/// `SubstExprBase` exists primarily to provide a non-templated base type -/// for `SubstExpr`. Code should prefer to use `SubstExpr` instead -/// of `SubstExprBase` as often as possible. -/// -struct SubstExprBase -{ -public: - /// Initialize as a null expression - SubstExprBase() {} - /// Initialize as the given `expr` with no subsitutions applied - SubstExprBase(Expr* expr) - : m_expr(expr) + struct SubstitutionSet { - } + DeclRefBase* declRef = nullptr; - /// Initialize as the given `expr` with the given `substs` applied - SubstExprBase(Expr* expr, SubstitutionSet const& substs) - : m_expr(expr), m_substs(substs) - { - } + // The element index if the substitution is happening inside a pack expansion. + // For example, if we are substituting the pattern type of `expand each T`, where + // `T` is a type pack, then packExpansionIndex will have a value starting from 0 + // to the count of the type pack during expansion of the `expand` type when we + // substitute `each T` with the element of `T` at index `packExpansionIndex`. + int packExpansionIndex = -1; + + SubstitutionSet() = default; + SubstitutionSet(DeclRefBase* declRefBase) + : declRef(declRefBase) + { + } + explicit operator bool() const; - /// Get the underlying expression without any substitutions - Expr* getExpr() const { return m_expr; } + template + void forEachGenericSubstitution(F func) const; - /// Get the subsitutions being applied, if any - SubstitutionSet const& getSubsts() const { return m_substs; } + template + void forEachSubstitutionArg(F func) const; -private: - Expr* m_expr = nullptr; - SubstitutionSet m_substs; + Type* applyToType(ASTBuilder* astBuilder, Type* type) const; + DeclRefBase* applyToDeclRef(ASTBuilder* astBuilder, DeclRefBase* declRef) const; - typedef void (SubstExprBase::*SafeBool)(); - void SafeBoolTrue() {} + LookupDeclRef* findLookupDeclRef() const; + GenericAppDeclRef* findGenericAppDeclRef(GenericDecl* genericDecl) const; + GenericAppDeclRef* findGenericAppDeclRef() const; + DeclRefBase* getInnerMostNodeWithSubstInfo() const; + }; -public: - /// Test whether this is a non-null expression - operator SafeBool() { return m_expr ? &SubstExprBase::SafeBoolTrue : nullptr; } + /// An expression together with (optional) substutions to apply to it + /// + /// Under the hood this is a pair of an `Expr*` and a `SubstitutionSet`. + /// Conceptually it represents the result of applying the substitutions, + /// recursively, to the given expression. + /// + /// `SubstExprBase` exists primarily to provide a non-templated base type + /// for `SubstExpr`. Code should prefer to use `SubstExpr` instead + /// of `SubstExprBase` as often as possible. + /// + struct SubstExprBase + { + public: + /// Initialize as a null expression + SubstExprBase() {} - /// Test whether this is a null expression - bool operator!() const { return m_expr == nullptr; } -}; + /// Initialize as the given `expr` with no subsitutions applied + SubstExprBase(Expr* expr) + : m_expr(expr) + { + } -/// An expression together with (optional) substutions to apply to it -/// -/// Under the hood this is a pair of an `T*` (there `T: Expr`) and a `SubstitutionSet`. -/// Conceptually it represents the result of applying the substitutions, -/// recursively, to the given expression. -/// -template -struct SubstExpr : SubstExprBase -{ -private: - typedef SubstExprBase Super; + /// Initialize as the given `expr` with the given `substs` applied + SubstExprBase(Expr* expr, SubstitutionSet const& substs) + : m_expr(expr), m_substs(substs) + { + } -public: - /// Initialize as a null expression - SubstExpr() {} + /// Get the underlying expression without any substitutions + Expr* getExpr() const { return m_expr; } - /// Initialize as the given `expr` with no subsitutions applied - SubstExpr(T* expr) - : Super(expr) - { - } + /// Get the subsitutions being applied, if any + SubstitutionSet const& getSubsts() const { return m_substs; } - /// Initialize as the given `expr` with the given `substs` applied - SubstExpr(T* expr, SubstitutionSet const& substs) - : Super(expr, substs) - { - } + private: + Expr* m_expr = nullptr; + SubstitutionSet m_substs; - /// Initialize as a copy of the given `other` expression - template - SubstExpr( - SubstExpr const& other, - typename EnableIf::Value, void>::type* = 0) - : Super(other.getExpr(), other.getSubsts()) - { - } + typedef void (SubstExprBase::*SafeBool)(); + void SafeBoolTrue() {} - /// Get the underlying expression without any substitutions - T* getExpr() const { return (T*)Super::getExpr(); } + public: + /// Test whether this is a non-null expression + operator SafeBool() { return m_expr ? &SubstExprBase::SafeBoolTrue : nullptr; } - /// Dynamic cast to an expression of type `U` + /// Test whether this is a null expression + bool operator!() const { return m_expr == nullptr; } + }; + + /// An expression together with (optional) substutions to apply to it /// - /// Returns a null expression if the cast fails, or if this expression was null. - template - SubstExpr as() + /// Under the hood this is a pair of an `T*` (there `T: Expr`) and a `SubstitutionSet`. + /// Conceptually it represents the result of applying the substitutions, + /// recursively, to the given expression. + /// + template + struct SubstExpr : SubstExprBase { - return SubstExpr(Slang::as(getExpr()), getSubsts()); - } -}; + private: + typedef SubstExprBase Super; -SubstExpr applySubstitutionToExpr(SubstitutionSet substSet, Expr* expr); + public: + /// Initialize as a null expression + SubstExpr() {} -class ASTBuilder; + /// Initialize as the given `expr` with no subsitutions applied + SubstExpr(T* expr) + : Super(expr) + { + } -template -struct DeclRef; -Module* getModule(Decl* decl); + /// Initialize as the given `expr` with the given `substs` applied + SubstExpr(T* expr, SubstitutionSet const& substs) + : Super(expr, substs) + { + } + /// Initialize as a copy of the given `other` expression + template + SubstExpr( + SubstExpr const& other, + typename EnableIf::Value, void>::type* = 0) + : Super(other.getExpr(), other.getSubsts()) + { + } -// If this is a declref to an associatedtype with a ThisTypeSubsitution, -// try to find the concrete decl that satisfies the associatedtype requirement from the -// concrete type supplied by ThisTypeSubstittution. -Val* _tryLookupConcreteAssociatedTypeFromThisTypeSubst(ASTBuilder* builder, DeclRef declRef); + /// Get the underlying expression without any substitutions + T* getExpr() const { return (T*)Super::getExpr(); } -template -struct DeclRef -{ - friend class ASTBuilder; + /// Dynamic cast to an expression of type `U` + /// + /// Returns a null expression if the cast fails, or if this expression was null. + template + SubstExpr as() + { + return SubstExpr(Slang::as(getExpr()), getSubsts()); + } + }; -public: - typedef T DeclType; - DeclRefBase* declRefBase; - DeclRef() - : declRefBase(nullptr) - { - } + SubstExpr applySubstitutionToExpr(SubstitutionSet substSet, Expr * expr); + + class ASTBuilder; - void init(DeclRefBase* base); + template + struct DeclRef; + Module* getModule(Decl * decl); - DeclRef(Decl* decl); - DeclRef(DeclRefBase* base) { init(base); } + // If this is a declref to an associatedtype with a ThisTypeSubsitution, + // try to find the concrete decl that satisfies the associatedtype requirement from the + // concrete type supplied by ThisTypeSubstittution. + Val* _tryLookupConcreteAssociatedTypeFromThisTypeSubst( + ASTBuilder * builder, + DeclRef declRef); - template::Value, void>::type> - DeclRef(DeclRef const& other) - : declRefBase(other.declRefBase) + template + struct DeclRef { - } + friend class ASTBuilder; - T* getDecl() const; - - Name* getName() const; + public: + typedef T DeclType; + DeclRefBase* declRefBase; + DeclRef() + : declRefBase(nullptr) + { + } - SourceLoc getNameLoc() const; - SourceLoc getLoc() const; - DeclRef getParent() const; - HashCode getHashCode() const; - Type* substitute(ASTBuilder* astBuilder, Type* type) const; + void init(DeclRefBase* base); - SubstExpr substitute(ASTBuilder* astBuilder, Expr* expr) const; + DeclRef(Decl* decl); - // Apply substitutions to a type or declaration - template - DeclRef substitute(ASTBuilder* astBuilder, DeclRef declRef) const; + DeclRef(DeclRefBase* base) { init(base); } - // Apply substitutions to this declaration reference - DeclRef substituteImpl(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff) const; + template::Value, void>::type> + DeclRef(DeclRef const& other) + : declRefBase(other.declRefBase) + { + } - template - DeclRef as() const - { - DeclRef result = DeclRef(declRefBase); - return result; - } + T* getDecl() const; - template - bool is() const - { - return Slang::as(static_cast(getDecl())) != nullptr; - } + Name* getName() const; - operator DeclRefBase*() const { return declRefBase; } + SourceLoc getNameLoc() const; + SourceLoc getLoc() const; + DeclRef getParent() const; + HashCode getHashCode() const; + Type* substitute(ASTBuilder* astBuilder, Type* type) const; - operator DeclRef() const { return DeclRef(declRefBase); } + SubstExpr substitute(ASTBuilder* astBuilder, Expr* expr) const; - template - bool equals(DeclRef other) const - { - return declRefBase == other.declRefBase; - } + // Apply substitutions to a type or declaration + template + DeclRef substitute(ASTBuilder* astBuilder, DeclRef declRef) const; - template - bool operator==(DeclRef other) const - { - return equals(other); - } + // Apply substitutions to this declaration reference + DeclRef substituteImpl(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff) const; - template - bool operator!=(DeclRef other) const - { - return !equals(other); - } + template + DeclRef as() const + { + DeclRef result = DeclRef(declRefBase); + return result; + } - explicit operator bool() const { return declRefBase; } -}; + template + bool is() const + { + return Slang::as(static_cast(getDecl())) != nullptr; + } -template -inline DeclRef makeDeclRef(T* decl) -{ - return DeclRef(decl); -} + operator DeclRefBase*() const { return declRefBase; } -SubstExpr substituteExpr(SubstitutionSet const& substs, Expr* expr); -DeclRef substituteDeclRef( - SubstitutionSet const& substs, - ASTBuilder* astBuilder, - DeclRef const& declRef); -Type* substituteType(SubstitutionSet const& substs, ASTBuilder* astBuilder, Type* type); + operator DeclRef() const { return DeclRef(declRefBase); } -enum class MemberFilterStyle -{ - All, ///< All members - Instance, ///< Only instance members - Static, ///< Only static (ie non instance) members -}; - -Decl* const* adjustFilterCursorImpl( - const ReflectClassInfo& clsInfo, - MemberFilterStyle filterStyle, - Decl* const* ptr, - Decl* const* end); -Decl* const* getFilterCursorByIndexImpl( - const ReflectClassInfo& clsInfo, - MemberFilterStyle filterStyle, - Decl* const* ptr, - Decl* const* end, - Index index); -Index getFilterCountImpl( - const ReflectClassInfo& clsInfo, - MemberFilterStyle filterStyle, - Decl* const* ptr, - Decl* const* end); - - -template -Decl* const* adjustFilterCursor(MemberFilterStyle filterStyle, Decl* const* ptr, Decl* const* end) -{ - return adjustFilterCursorImpl(getSyntaxClass(), filterStyle, ptr, end); -} - -/// Finds the element at index. If there is no element at the index (for example has too few -/// elements), returns nullptr. -template -Decl* const* getFilterCursorByIndex( - MemberFilterStyle filterStyle, - Decl* const* ptr, - Decl* const* end, - Index index) -{ - return getFilterCursorByIndexImpl(getSyntaxClass(), filterStyle, ptr, end, index); -} + template + bool equals(DeclRef other) const + { + return declRefBase == other.declRefBase; + } -template -Index getFilterCount(MemberFilterStyle filterStyle, Decl* const* ptr, Decl* const* end) -{ - return getFilterCountImpl(getSyntaxClass(), filterStyle, ptr, end); -} + template + bool operator==(DeclRef other) const + { + return equals(other); + } -template -bool isFilterNonEmpty(MemberFilterStyle filterStyle, Decl* const* ptr, Decl* const* end) -{ - return adjustFilterCursorImpl(getSyntaxClass(), filterStyle, ptr, end) != end; -} + template + bool operator!=(DeclRef other) const + { + return !equals(other); + } -template -struct FilteredMemberList -{ - typedef Decl* Element; + explicit operator bool() const { return declRefBase; } + }; - FilteredMemberList() - : m_begin(nullptr), m_end(nullptr) + template + inline DeclRef makeDeclRef(T * decl) { + return DeclRef(decl); } - explicit FilteredMemberList( - List const& list, - MemberFilterStyle filterStyle = MemberFilterStyle::All) - : m_begin(adjustFilterCursor(filterStyle, list.begin(), list.end())) - , m_end(list.end()) - , m_filterStyle(filterStyle) - { - } + SubstExpr substituteExpr(SubstitutionSet const& substs, Expr* expr); + DeclRef substituteDeclRef( + SubstitutionSet const& substs, + ASTBuilder* astBuilder, + DeclRef const& declRef); + Type* substituteType(SubstitutionSet const& substs, ASTBuilder* astBuilder, Type* type); - struct Iterator + enum class MemberFilterStyle { - const Element* m_cursor; - const Element* m_end; - MemberFilterStyle m_filterStyle; - - bool operator!=(Iterator const& other) const { return m_cursor != other.m_cursor; } + All, ///< All members + Instance, ///< Only instance members + Static, ///< Only static (ie non instance) members + }; - void operator++() { m_cursor = adjustFilterCursor(m_filterStyle, m_cursor + 1, m_end); } + Decl* const* adjustFilterCursorImpl( + const ReflectClassInfo& clsInfo, + MemberFilterStyle filterStyle, + Decl* const* ptr, + Decl* const* end); + Decl* const* getFilterCursorByIndexImpl( + const ReflectClassInfo& clsInfo, + MemberFilterStyle filterStyle, + Decl* const* ptr, + Decl* const* end, + Index index); + Index getFilterCountImpl( + const ReflectClassInfo& clsInfo, + MemberFilterStyle filterStyle, + Decl* const* ptr, + Decl* const* end); - T* operator*() { return static_cast(*m_cursor); } - }; - Iterator begin() + template + Decl* const* adjustFilterCursor( + MemberFilterStyle filterStyle, + Decl* const* ptr, + Decl* const* end) { - Iterator iter = {m_begin, m_end, m_filterStyle}; - return iter; + return adjustFilterCursorImpl(getSyntaxClass(), filterStyle, ptr, end); } - Iterator end() + /// Finds the element at index. If there is no element at the index (for example has too few + /// elements), returns nullptr. + template + Decl* const* getFilterCursorByIndex( + MemberFilterStyle filterStyle, + Decl* const* ptr, + Decl* const* end, + Index index) { - Iterator iter = {m_end, m_end, m_filterStyle}; - return iter; + return getFilterCursorByIndexImpl(getSyntaxClass(), filterStyle, ptr, end, index); } - // TODO(tfoley): It is ugly to have these. - // We should probably fix the call sites instead. - T* getFirst() { return *begin(); } - Index getCount() { return getFilterCount(m_filterStyle, m_begin, m_end); } - - T* operator[](Index index) const + template + Index getFilterCount(MemberFilterStyle filterStyle, Decl* const* ptr, Decl* const* end) { - Decl* const* ptr = getFilterCursorByIndex(m_filterStyle, m_begin, m_end, index); - SLANG_ASSERT(ptr); - return static_cast(*ptr); + return getFilterCountImpl(getSyntaxClass(), filterStyle, ptr, end); } - /// Returns true if empty (equivalent to getCount() == 0) - bool isEmpty() const + template + bool isFilterNonEmpty(MemberFilterStyle filterStyle, Decl* const* ptr, Decl* const* end) { - /// Note we don't have to scan, because m_begin has already been adjusted, when the - /// FilteredMemberList is constructed - return m_begin == m_end; + return adjustFilterCursorImpl(getSyntaxClass(), filterStyle, ptr, end) != end; } - /// Returns true if non empty (equivalent to getCount() != 0 but faster) - bool isNonEmpty() const { return !isEmpty(); } - List toList() + template + struct FilteredMemberList { - List result; - for (auto element : (*this)) + typedef Decl* Element; + + FilteredMemberList() + : m_begin(nullptr), m_end(nullptr) { - result.add(element); } - return result; - } - const Element* - m_begin; ///< Is either equal to m_end, or points to first *valid* filtered member - const Element* m_end; - MemberFilterStyle m_filterStyle; -}; + explicit FilteredMemberList( + List const& list, + MemberFilterStyle filterStyle = MemberFilterStyle::All) + : m_begin(adjustFilterCursor(filterStyle, list.begin(), list.end())) + , m_end(list.end()) + , m_filterStyle(filterStyle) + { + } -struct TransparentMemberInfo -{ - // The declaration of the transparent member - Decl* decl = nullptr; -}; + struct Iterator + { + const Element* m_cursor; + const Element* m_end; + MemberFilterStyle m_filterStyle; -template -struct FilteredMemberRefList -{ - List const& m_decls; - DeclRef m_parent; - MemberFilterStyle m_filterStyle; - ASTBuilder* m_astBuilder; + bool operator!=(Iterator const& other) const { return m_cursor != other.m_cursor; } - FilteredMemberRefList( - ASTBuilder* astBuilder, - List const& decls, - DeclRef parent, - MemberFilterStyle filterStyle = MemberFilterStyle::All) - : m_decls(decls), m_parent(parent), m_filterStyle(filterStyle), m_astBuilder(astBuilder) - { - } + void operator++() + { + m_cursor = adjustFilterCursor(m_filterStyle, m_cursor + 1, m_end); + } - Index getCount() const - { - return getFilterCount(m_filterStyle, m_decls.begin(), m_decls.end()); - } + T* operator*() { return static_cast(*m_cursor); } + }; - /// True if empty (equivalent to getCount == 0, but faster) - bool isEmpty() const { return !isNonEmpty(); } - /// True if non empty (equivalent to getCount() != 0 but faster) - bool isNonEmpty() const - { - return isFilterNonEmpty(m_filterStyle, m_decls.begin(), m_decls.end()); - } + Iterator begin() + { + Iterator iter = {m_begin, m_end, m_filterStyle}; + return iter; + } + + Iterator end() + { + Iterator iter = {m_end, m_end, m_filterStyle}; + return iter; + } - DeclRef getFirstOrNull() { return isEmpty() ? DeclRef() : (*this)[0]; } + // TODO(tfoley): It is ugly to have these. + // We should probably fix the call sites instead. + T* getFirst() { return *begin(); } + Index getCount() { return getFilterCount(m_filterStyle, m_begin, m_end); } - DeclRef operator[](Index index) const - { - Decl* const* decl = - getFilterCursorByIndex(m_filterStyle, m_decls.begin(), m_decls.end(), index); - SLANG_ASSERT(decl); - return _getMemberDeclRef(m_astBuilder, m_parent, (T*)*decl).template as(); - } + T* operator[](Index index) const + { + Decl* const* ptr = getFilterCursorByIndex(m_filterStyle, m_begin, m_end, index); + SLANG_ASSERT(ptr); + return static_cast(*ptr); + } - List> toArray() const + /// Returns true if empty (equivalent to getCount() == 0) + bool isEmpty() const + { + /// Note we don't have to scan, because m_begin has already been adjusted, when the + /// FilteredMemberList is constructed + return m_begin == m_end; + } + /// Returns true if non empty (equivalent to getCount() != 0 but faster) + bool isNonEmpty() const { return !isEmpty(); } + + List toList() + { + List result; + for (auto element : (*this)) + { + result.add(element); + } + return result; + } + + const Element* + m_begin; ///< Is either equal to m_end, or points to first *valid* filtered member + const Element* m_end; + MemberFilterStyle m_filterStyle; + }; + + struct TransparentMemberInfo { - List> result; - for (auto d : *this) - result.add(d); - return result; - } + // The declaration of the transparent member + Decl* decl = nullptr; + }; - struct Iterator + template + struct FilteredMemberRefList { - FilteredMemberRefList const* m_list; - Decl* const* m_ptr; - Decl* const* m_end; + List const& m_decls; + DeclRef m_parent; MemberFilterStyle m_filterStyle; - - Iterator() - : m_list(nullptr), m_ptr(nullptr), m_filterStyle(MemberFilterStyle::All) + ASTBuilder* m_astBuilder; + + FilteredMemberRefList( + ASTBuilder* astBuilder, + List const& decls, + DeclRef parent, + MemberFilterStyle filterStyle = MemberFilterStyle::All) + : m_decls(decls), m_parent(parent), m_filterStyle(filterStyle), m_astBuilder(astBuilder) { } - Iterator( - FilteredMemberRefList const* list, - Decl* const* ptr, - Decl* const* end, - MemberFilterStyle filterStyle) - : m_list(list), m_ptr(ptr), m_end(end), m_filterStyle(filterStyle) + + Index getCount() const { + return getFilterCount(m_filterStyle, m_decls.begin(), m_decls.end()); } - bool operator!=(const Iterator& other) const { return m_ptr != other.m_ptr; } + /// True if empty (equivalent to getCount == 0, but faster) + bool isEmpty() const { return !isNonEmpty(); } + /// True if non empty (equivalent to getCount() != 0 but faster) + bool isNonEmpty() const + { + return isFilterNonEmpty(m_filterStyle, m_decls.begin(), m_decls.end()); + } - void operator++() { m_ptr = adjustFilterCursor(m_filterStyle, m_ptr + 1, m_end); } + DeclRef getFirstOrNull() { return isEmpty() ? DeclRef() : (*this)[0]; } - DeclRef operator*() + DeclRef operator[](Index index) const { - return _getMemberDeclRef(m_list->m_astBuilder, m_list->m_parent, (T*)*m_ptr) - .template as(); + Decl* const* decl = + getFilterCursorByIndex(m_filterStyle, m_decls.begin(), m_decls.end(), index); + SLANG_ASSERT(decl); + return _getMemberDeclRef(m_astBuilder, m_parent, (T*)*decl).template as(); } - }; - Iterator begin() const - { - return Iterator( - this, - adjustFilterCursor(m_filterStyle, m_decls.begin(), m_decls.end()), - m_decls.end(), - m_filterStyle); - } - Iterator end() const { return Iterator(this, m_decls.end(), m_decls.end(), m_filterStyle); } -}; + List> toArray() const + { + List> result; + for (auto d : *this) + result.add(d); + return result; + } -// -// type Expressions -// + struct Iterator + { + FilteredMemberRefList const* m_list; + Decl* const* m_ptr; + Decl* const* m_end; + MemberFilterStyle m_filterStyle; + + Iterator() + : m_list(nullptr), m_ptr(nullptr), m_filterStyle(MemberFilterStyle::All) + { + } + Iterator( + FilteredMemberRefList const* list, + Decl* const* ptr, + Decl* const* end, + MemberFilterStyle filterStyle) + : m_list(list), m_ptr(ptr), m_end(end), m_filterStyle(filterStyle) + { + } + + bool operator!=(const Iterator& other) const { return m_ptr != other.m_ptr; } + + void operator++() { m_ptr = adjustFilterCursor(m_filterStyle, m_ptr + 1, m_end); } + + DeclRef operator*() + { + return _getMemberDeclRef(m_list->m_astBuilder, m_list->m_parent, (T*)*m_ptr) + .template as(); + } + }; + + Iterator begin() const + { + return Iterator( + this, + adjustFilterCursor(m_filterStyle, m_decls.begin(), m_decls.end()), + m_decls.end(), + m_filterStyle); + } + Iterator end() const { return Iterator(this, m_decls.end(), m_decls.end(), m_filterStyle); } + }; -// 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. -FIDDLE() -struct TypeExp -{ - FIDDLE(...) - typedef TypeExp ThisType; + // + // type Expressions + // - TypeExp() {} - TypeExp(TypeExp const& other) - : exp(other.exp), type(other.type) - { - } - explicit TypeExp(Expr* exp) - : exp(exp) - { - } - explicit TypeExp(Type* type) - : type(type) + // 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. + FIDDLE() + struct TypeExp { - } - TypeExp(Expr* exp, Type* type) - : exp(exp), type(type) - { - } + FIDDLE(...) + typedef TypeExp ThisType; - Expr* exp = nullptr; - Type* type = nullptr; + TypeExp() {} + TypeExp(TypeExp const& other) + : exp(other.exp), type(other.type) + { + } + explicit TypeExp(Expr* exp) + : exp(exp) + { + } + explicit TypeExp(Type* type) + : type(type) + { + } + TypeExp(Expr* exp, Type* type) + : exp(exp), type(type) + { + } - bool equals(Type* other); + Expr* exp = nullptr; + Type* type = nullptr; - Type* Ptr() { return type; } - operator Type*() { return type; } - Type* operator->() { return Ptr(); } + bool equals(Type* other); - ThisType& operator=(const ThisType& rhs) = default; + Type* Ptr() { return type; } + operator Type*() { return type; } + Type* operator->() { return Ptr(); } - /// A global immutable TypeExp, that has no type or exp set. - static const TypeExp empty; -}; + ThisType& operator=(const ThisType& rhs) = default; -// Masks to be applied when lookup up declarations -enum class LookupMask : uint8_t -{ - type = 0x1, - Function = 0x2, - Value = 0x4, - Attribute = 0x8, - SyntaxDecl = 0x10, - Default = type | Function | Value | SyntaxDecl, -}; - -/// Flags for options to be used when looking up declarations -enum class LookupOptions : uint8_t -{ - None = 0, - IgnoreBaseInterfaces = 1 << 0, - Completion = 1 << 1, ///< Lookup all applicable decls for code completion suggestions - NoDeref = 1 << 2, - ConsiderAllLocalNamesInScope = 1 << 3, - ///^ Normally we rely on the checking state of local names to determine - /// if they have been declared. If the scopes are currently - /// "under-construction" and not being checked, then it's safe to - /// consider all names we've inserted so far. This is used when - /// checking to see if a keyword is shadowed. - IgnoreInheritance = - 1 << 4, ///< Lookup only non inheritance children of a struct (including `extension`) - IgnoreTransparentMembers = 1 << 5, -}; -inline LookupOptions operator&(LookupOptions a, LookupOptions b) -{ - return (LookupOptions)((std::underlying_type_t)a & - (std::underlying_type_t)b); -} + /// A global immutable TypeExp, that has no type or exp set. + static const TypeExp empty; + }; -class LookupResultItem_Breadcrumb : public RefObject -{ -public: - enum class Kind : uint8_t + // Masks to be applied when lookup up declarations + enum class LookupMask : uint8_t { - // The lookup process looked "through" an in-scope - // declaration to the fields inside of it, so that - // even if lookup started with a simple name `f`, - // it needs to result in a member expression `obj.f`. - Member, - - // The lookup process took a pointer(-like) value, and then - // proceeded to derefence it and look at the thing(s) - // it points to instead, so that the final expression - // needs to have `(*obj)` - Deref, - - // The lookup process saw a value `obj` of type `T` and - // took into account an in-scope constraint that says - // `T` is a subtype of some other type `U`, so that - // lookup was able to find a member through type `U` - // instead. - SuperType, - - // The lookup process considered a member of an - // enclosing type as being in scope, so that any - // reference to that member needs to use a `this` - // expression as appropriate. - This, + type = 0x1, + Function = 0x2, + Value = 0x4, + Attribute = 0x8, + SyntaxDecl = 0x10, + Default = type | Function | Value | SyntaxDecl, }; - // The kind of lookup step that was performed - Kind kind; + /// Flags for options to be used when looking up declarations + enum class LookupOptions : uint8_t + { + None = 0, + IgnoreBaseInterfaces = 1 << 0, + Completion = 1 << 1, ///< Lookup all applicable decls for code completion suggestions + NoDeref = 1 << 2, + ConsiderAllLocalNamesInScope = 1 << 3, + ///^ Normally we rely on the checking state of local names to determine + /// if they have been declared. If the scopes are currently + /// "under-construction" and not being checked, then it's safe to + /// consider all names we've inserted so far. This is used when + /// checking to see if a keyword is shadowed. + IgnoreInheritance = + 1 << 4, ///< Lookup only non inheritance children of a struct (including `extension`) + IgnoreTransparentMembers = 1 << 5, + }; + inline LookupOptions operator&(LookupOptions a, LookupOptions b) + { + return (LookupOptions)((std::underlying_type_t)a & + (std::underlying_type_t)b); + } - // For the `Kind::This` case, what does the implicit - // `this` or `This` parameter refer to? - // - enum class ThisParameterMode : uint8_t + class LookupResultItem_Breadcrumb : public RefObject { - ImmutableValue, // An immutable `this` value - MutableValue, // A mutable `this` value - Type, // A `This` type + public: + enum class Kind : uint8_t + { + // The lookup process looked "through" an in-scope + // declaration to the fields inside of it, so that + // even if lookup started with a simple name `f`, + // it needs to result in a member expression `obj.f`. + Member, + + // The lookup process took a pointer(-like) value, and then + // proceeded to derefence it and look at the thing(s) + // it points to instead, so that the final expression + // needs to have `(*obj)` + Deref, + + // The lookup process saw a value `obj` of type `T` and + // took into account an in-scope constraint that says + // `T` is a subtype of some other type `U`, so that + // lookup was able to find a member through type `U` + // instead. + SuperType, + + // The lookup process considered a member of an + // enclosing type as being in scope, so that any + // reference to that member needs to use a `this` + // expression as appropriate. + This, + }; + + // The kind of lookup step that was performed + Kind kind; + + // For the `Kind::This` case, what does the implicit + // `this` or `This` parameter refer to? + // + enum class ThisParameterMode : uint8_t + { + ImmutableValue, // An immutable `this` value + MutableValue, // A mutable `this` value + Type, // A `This` type + + Default = ImmutableValue, + }; + ThisParameterMode thisParameterMode = ThisParameterMode::Default; + + // As needed, a reference to the declaration that faciliated + // the lookup step. + // + // For a `Member` lookup step, this is the declaration whose + // members were implicitly pulled into scope. + // + // For a `Constraint` lookup step, this is the `ConstraintDecl` + // that serves to witness the subtype relationship. + // + DeclRef declRef; + + Val* val = nullptr; + + // The next implicit step that the lookup process took to + // arrive at a final value. + RefPtr next; + + LookupResultItem_Breadcrumb( + Kind kind, + DeclRef declRef, + Val* val, + RefPtr next, + ThisParameterMode thisParameterMode = ThisParameterMode::Default) + : kind(kind) + , thisParameterMode(thisParameterMode) + , declRef(declRef) + , val(val) + , next(next) + { + } - Default = ImmutableValue, + protected: + // Needed for serialization + LookupResultItem_Breadcrumb() = default; }; - ThisParameterMode thisParameterMode = ThisParameterMode::Default; - - // As needed, a reference to the declaration that faciliated - // the lookup step. - // - // For a `Member` lookup step, this is the declaration whose - // members were implicitly pulled into scope. - // - // For a `Constraint` lookup step, this is the `ConstraintDecl` - // that serves to witness the subtype relationship. - // - DeclRef declRef; - Val* val = nullptr; + // Represents one item found during lookup + struct LookupResultItem + { + typedef LookupResultItem_Breadcrumb Breadcrumb; + + // Sometimes lookup finds an item, but there were additional + // "hops" taken to reach it. We need to remember these steps + // so that if/when we consturct a full expression we generate + // appropriate AST nodes for all the steps. + // + // We build up a list of these "breadcrumbs" while doing + // lookup, and store them alongside each item found. + // + // As an example, suppose we have an HLSL `cbuffer` declaration: + // + // cbuffer C { float4 f; } + // + // This is syntax sugar for a global-scope variable of + // type `ConstantBuffer` where `T` is a `struct` containing + // all the members: + // + // struct Anon0 { float4 f; }; + // __transparent ConstantBuffer anon1; + // + // The `__transparent` modifier there captures the fact that + // when somebody writes `f` in their code, they expect it to + // "see through" the `cbuffer` declaration (or the global variable, + // in this case) and find the member inside. + // + // But when the user writes `f` we can't just create a simple + // `VarExpr` that refers directly to that field, because that + // doesn't actually reflect the required steps in a way that + // code generation can use. + // + // Instead we need to construct an expression like `(*anon1).f`, + // where there is are two additional steps in the process: + // + // 1. We needed to dereference the pointer-like type `ConstantBuffer` + // to get at a value of type `Anon0` + // 2. We needed to access a sub-field of the aggregate type `Anon0` + // + // We *could* just create these full-formed expressions during + // lookup, but this might mean creating a large number of + // AST nodes in cases where the user calls an overloaded function. + // At the very least we'd rather not heap-allocate in the common + // case where no "extra" steps need to be performed to get to + // the declarations. + // + // This is where "breadcrumbs" come in. A breadcrumb represents + // an extra "step" that must be performed to turn a declaration + // found by lookup into a valid expression to splice into the + // AST. Most of the time lookup result items don't have any + // breadcrumbs, so that no extra heap allocation takes place. + // When an item does have breadcrumbs, and it is chosen as + // the unique result (perhaps by overload resolution), then + // we can walk the list of breadcrumbs to create a full + // expression. + + + // A properly-specialized reference to the declaration that was found. + DeclRef declRef; + + // Any breadcrumbs needed in order to turn that declaration + // reference into a well-formed expression. + // + // This is unused in the simple case where a declaration + // is being referenced directly (rather than through + // transparent members). + RefPtr breadcrumbs; + + LookupResultItem() = default; + explicit LookupResultItem(DeclRef declRef) + : declRef(declRef) + { + } + LookupResultItem(DeclRef declRef, RefPtr breadcrumbs) + : declRef(declRef), breadcrumbs(breadcrumbs) + { + } + }; - // The next implicit step that the lookup process took to - // arrive at a final value. - RefPtr next; - LookupResultItem_Breadcrumb( - Kind kind, - DeclRef declRef, - Val* val, - RefPtr next, - ThisParameterMode thisParameterMode = ThisParameterMode::Default) - : kind(kind), thisParameterMode(thisParameterMode), declRef(declRef), val(val), next(next) + // 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 simple case + LookupResultItem item; -protected: - // Needed for serialization - LookupResultItem_Breadcrumb() = default; -}; + // 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. + // + // Additionally, if `items` is used, then `item` *must* hold an item that + // is also in the items list (typically the first entry), as an invariant. + // Otherwise isValid/begin will not function correctly. + List items; -// Represents one item found during lookup -struct LookupResultItem -{ - typedef LookupResultItem_Breadcrumb Breadcrumb; + // Was at least one result found? + bool isValid() const { return item.declRef.getDecl() != nullptr; } - // Sometimes lookup finds an item, but there were additional - // "hops" taken to reach it. We need to remember these steps - // so that if/when we consturct a full expression we generate - // appropriate AST nodes for all the steps. - // - // We build up a list of these "breadcrumbs" while doing - // lookup, and store them alongside each item found. - // - // As an example, suppose we have an HLSL `cbuffer` declaration: - // - // cbuffer C { float4 f; } - // - // This is syntax sugar for a global-scope variable of - // type `ConstantBuffer` where `T` is a `struct` containing - // all the members: - // - // struct Anon0 { float4 f; }; - // __transparent ConstantBuffer anon1; - // - // The `__transparent` modifier there captures the fact that - // when somebody writes `f` in their code, they expect it to - // "see through" the `cbuffer` declaration (or the global variable, - // in this case) and find the member inside. - // - // But when the user writes `f` we can't just create a simple - // `VarExpr` that refers directly to that field, because that - // doesn't actually reflect the required steps in a way that - // code generation can use. - // - // Instead we need to construct an expression like `(*anon1).f`, - // where there is are two additional steps in the process: - // - // 1. We needed to dereference the pointer-like type `ConstantBuffer` - // to get at a value of type `Anon0` - // 2. We needed to access a sub-field of the aggregate type `Anon0` - // - // We *could* just create these full-formed expressions during - // lookup, but this might mean creating a large number of - // AST nodes in cases where the user calls an overloaded function. - // At the very least we'd rather not heap-allocate in the common - // case where no "extra" steps need to be performed to get to - // the declarations. - // - // This is where "breadcrumbs" come in. A breadcrumb represents - // an extra "step" that must be performed to turn a declaration - // found by lookup into a valid expression to splice into the - // AST. Most of the time lookup result items don't have any - // breadcrumbs, so that no extra heap allocation takes place. - // When an item does have breadcrumbs, and it is chosen as - // the unique result (perhaps by overload resolution), then - // we can walk the list of breadcrumbs to create a full - // expression. - - - // A properly-specialized reference to the declaration that was found. - DeclRef declRef; - - // Any breadcrumbs needed in order to turn that declaration - // reference into a well-formed expression. - // - // This is unused in the simple case where a declaration - // is being referenced directly (rather than through - // transparent members). - RefPtr breadcrumbs; - - LookupResultItem() = default; - explicit LookupResultItem(DeclRef declRef) - : declRef(declRef) - { - } - LookupResultItem(DeclRef declRef, RefPtr breadcrumbs) - : declRef(declRef), breadcrumbs(breadcrumbs) - { - } -}; + bool isOverloaded() const { return items.getCount() > 1; } + Name* getName() const + { + return items.getCount() > 1 ? items[0].declRef.getName() : item.declRef.getName(); + } + LookupResultItem* begin() const + { + if (isValid()) + { + if (isOverloaded()) + return const_cast(items.begin()); + else + return const_cast(&item); + } + else + return nullptr; + } + LookupResultItem* end() const + { + if (isValid()) + { + if (isOverloaded()) + return const_cast(items.end()); + else + return const_cast(&item + 1); + } + else + return nullptr; + } + }; -// 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 simple case - LookupResultItem item; + // A helper to avoid having to include slang-check-impl.h in slang-syntax.h + struct SemanticsVisitor; + ASTBuilder* semanticsVisitorGetASTBuilder(SemanticsVisitor*); - // 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. - // - // Additionally, if `items` is used, then `item` *must* hold an item that - // is also in the items list (typically the first entry), as an invariant. - // Otherwise isValid/begin will not function correctly. - List items; + struct LookupRequest + { + SemanticsVisitor* semantics = nullptr; + Scope* scope = nullptr; + Scope* endScope = nullptr; - // Was at least one result found? - bool isValid() const { return item.declRef.getDecl() != nullptr; } + // A decl to exclude from the lookup, used to exclude the current decl being checked, such + // as in typedef Foo Foo; to avoid finding itself. + Decl* declToExclude = nullptr; + LookupMask mask = LookupMask::Default; + LookupOptions options = LookupOptions::None; - bool isOverloaded() const { return items.getCount() > 1; } + bool isCompletionRequest() const + { + return (options & LookupOptions::Completion) != LookupOptions::None; + } + bool shouldConsiderAllLocalNames() const + { + return (options & LookupOptions::ConsiderAllLocalNamesInScope) != LookupOptions::None; + } + }; - Name* getName() const - { - return items.getCount() > 1 ? items[0].declRef.getName() : item.declRef.getName(); - } - LookupResultItem* begin() const + class WitnessTable; + + // A value that witnesses the satisfaction of an interface + // requirement by a particular declaration or value. + struct RequirementWitness { - if (isValid()) + RequirementWitness() + : m_flavor(Flavor::none) { - if (isOverloaded()) - return const_cast(items.begin()); - else - return const_cast(&item); } - else - return nullptr; - } - LookupResultItem* end() const - { - if (isValid()) + + RequirementWitness(DeclRefBase* declRef) + : m_flavor(Flavor::declRef), m_declRef(declRef) { - if (isOverloaded()) - return const_cast(items.end()); - else - return const_cast(&item + 1); } - else - return nullptr; - } -}; -// A helper to avoid having to include slang-check-impl.h in slang-syntax.h -struct SemanticsVisitor; -ASTBuilder* semanticsVisitorGetASTBuilder(SemanticsVisitor*); + RequirementWitness(Val* val); -struct LookupRequest -{ - SemanticsVisitor* semantics = nullptr; - Scope* scope = nullptr; - Scope* endScope = nullptr; + RequirementWitness(RefPtr witnessTable); - // A decl to exclude from the lookup, used to exclude the current decl being checked, such as in - // typedef Foo Foo; to avoid finding itself. - Decl* declToExclude = nullptr; - LookupMask mask = LookupMask::Default; - LookupOptions options = LookupOptions::None; - - bool isCompletionRequest() const - { - return (options & LookupOptions::Completion) != LookupOptions::None; - } - bool shouldConsiderAllLocalNames() const - { - return (options & LookupOptions::ConsiderAllLocalNamesInScope) != LookupOptions::None; - } -}; + enum class Flavor + { + none, + declRef, + val, + witnessTable, + }; -class WitnessTable; + Flavor getFlavor() const { return m_flavor; } -// A value that witnesses the satisfaction of an interface -// requirement by a particular declaration or value. -struct RequirementWitness -{ - RequirementWitness() - : m_flavor(Flavor::none) - { - } + DeclRef getDeclRef() + { + SLANG_ASSERT(getFlavor() == Flavor::declRef); + return m_declRef; + } - RequirementWitness(DeclRefBase* declRef) - : m_flavor(Flavor::declRef), m_declRef(declRef) - { - } + Val* getVal() + { + SLANG_ASSERT(getFlavor() == Flavor::val); + return m_val; + } - RequirementWitness(Val* val); + RefPtr getWitnessTable(); - RequirementWitness(RefPtr witnessTable); + RequirementWitness specialize(ASTBuilder* astBuilder, SubstitutionSet const& subst); - enum class Flavor - { - none, - declRef, - val, - witnessTable, + Flavor m_flavor; + DeclRef m_declRef; + RefPtr m_obj; + Val* m_val = nullptr; }; - Flavor getFlavor() const { return m_flavor; } + typedef OrderedDictionary RequirementDictionary; - DeclRef getDeclRef() + FIDDLE() + class WitnessTable : public RefObject { - SLANG_ASSERT(getFlavor() == Flavor::declRef); - return m_declRef; - } - - Val* getVal() - { - SLANG_ASSERT(getFlavor() == Flavor::val); - return m_val; - } + FIDDLE(...) + const RequirementDictionary& getRequirementDictionary() { return m_requirementDictionary; } - RefPtr getWitnessTable(); + void add(Decl* decl, RequirementWitness const& witness); - RequirementWitness specialize(ASTBuilder* astBuilder, SubstitutionSet const& subst); + // The type that the witness table witnesses conformance to (e.g. an Interface) + Type* baseType; - Flavor m_flavor; - DeclRef m_declRef; - RefPtr m_obj; - Val* m_val = nullptr; -}; + // The type witnessesd by the witness table (a concrete type). + Type* witnessedType; -typedef OrderedDictionary RequirementDictionary; + // Whether or not this witness table is an extern declaration. + bool isExtern = false; -FIDDLE() -class WitnessTable : public RefObject -{ - FIDDLE(...) - const RequirementDictionary& getRequirementDictionary() { return m_requirementDictionary; } + // Cached dictionary for looking up satisfying values. + RequirementDictionary m_requirementDictionary; - void add(Decl* decl, RequirementWitness const& witness); + RefPtr specialize(ASTBuilder* astBuilder, SubstitutionSet const& subst); + }; - // The type that the witness table witnesses conformance to (e.g. an Interface) - Type* baseType; + struct SpecializationParam + { + enum class Flavor + { + GenericType, + GenericValue, + ExistentialType, + ExistentialValue, + }; + Flavor flavor; + SourceLoc loc; + NodeBase* object = nullptr; + }; + typedef List SpecializationParams; - // The type witnessesd by the witness table (a concrete type). - Type* witnessedType; + struct SpecializationArg + { + Val* val = nullptr; + }; + typedef List SpecializationArgs; - // Whether or not this witness table is an extern declaration. - bool isExtern = false; + struct ExpandedSpecializationArg : SpecializationArg + { + Val* witness = nullptr; + }; + typedef List ExpandedSpecializationArgs; - // Cached dictionary for looking up satisfying values. - RequirementDictionary m_requirementDictionary; + /// A reference-counted object to hold a list of candidate extensions + /// that might be applicable to a type based on its declaration. + /// + FIDDLE() + class CandidateExtensionList : public RefObject + { + FIDDLE(...) + List candidateExtensions; + }; - RefPtr specialize(ASTBuilder* astBuilder, SubstitutionSet const& subst); -}; -struct SpecializationParam -{ - enum class Flavor + enum class DeclAssociationKind { - GenericType, - GenericValue, - ExistentialType, - ExistentialValue, + ForwardDerivativeFunc, + BackwardDerivativeFunc, + PrimalSubstituteFunc }; - Flavor flavor; - SourceLoc loc; - NodeBase* object = nullptr; -}; -typedef List SpecializationParams; - -struct SpecializationArg -{ - Val* val = nullptr; -}; -typedef List SpecializationArgs; -struct ExpandedSpecializationArg : SpecializationArg -{ - Val* witness = nullptr; -}; -typedef List ExpandedSpecializationArgs; - -/// A reference-counted object to hold a list of candidate extensions -/// that might be applicable to a type based on its declaration. -/// -FIDDLE() -class CandidateExtensionList : public RefObject -{ - FIDDLE(...) - List candidateExtensions; -}; + FIDDLE() + class DeclAssociation : public RefObject + { + FIDDLE(...) + DeclAssociationKind kind; + Decl* decl; + }; + /// A reference-counted object to hold a list of associated decls for a decl. + /// + FIDDLE() + class DeclAssociationList : public RefObject + { + FIDDLE(...) + List> associations; + }; -enum class DeclAssociationKind -{ - ForwardDerivativeFunc, - BackwardDerivativeFunc, - PrimalSubstituteFunc -}; + /// Represents the "direction" that a parameter is being passed (e.g., `in` or `out` + enum ParameterDirection + { + kParameterDirection_In, ///< Copy in + kParameterDirection_Out, ///< Copy out + kParameterDirection_InOut, ///< Copy in, copy out + kParameterDirection_Ref, ///< By-reference + kParameterDirection_ConstRef, ///< By-const-reference + }; -FIDDLE() -class DeclAssociation : public RefObject -{ - FIDDLE(...) - DeclAssociationKind kind; - Decl* decl; -}; - -/// A reference-counted object to hold a list of associated decls for a decl. -/// -FIDDLE() -class DeclAssociationList : public RefObject -{ - FIDDLE(...) - List> associations; -}; + void printDiagnosticArg(StringBuilder & sb, ParameterDirection direction); + + /// The kind of a builtin interface requirement that can be automatically synthesized. + enum class BuiltinRequirementKind + { + DefaultInitializableConstructor, ///< The `IDefaultInitializable.__init()` method + + DifferentialType, ///< The `IDifferentiable.Differential` associated type requirement + DifferentialPtrType, ///< The `IDifferentiable.DifferentialPtr` associated type requirement + DZeroFunc, ///< The `IDifferentiable.dzero` function requirement + DAddFunc, ///< The `IDifferentiable.dadd` function requirement + DMulFunc, ///< The `IDifferentiable.dmul` function requirement + + InitLogicalFromInt, ///< The `ILogical.__init` mtehod. + Equals, ///< The `ILogical.equals` mtehod. + LessThan, ///< The `ILogical.lessThan` mtehod. + LessThanOrEquals, ///< The `ILogical.lessThanOrEquals` mtehod. + Shl, ///< The `ILogical.shl` mtehod. + Shr, ///< The `ILogical.shr` mtehod. + BitAnd, ///< The `ILogical.bitAnd` mtehod. + BitOr, ///< The `ILogical.bitOr` mtehod. + BitXor, ///< The `ILogical.bitXor` mtehod. + BitNot, ///< The `ILogical.bitNot` mtehod. + And, ///< The `ILogical.and` mtehod. + Or, ///< The `ILogical.or` mtehod. + Not, ///< The `ILogical.not` mtehod. + }; -/// Represents the "direction" that a parameter is being passed (e.g., `in` or `out` -enum ParameterDirection -{ - kParameterDirection_In, ///< Copy in - kParameterDirection_Out, ///< Copy out - kParameterDirection_InOut, ///< Copy in, copy out - kParameterDirection_Ref, ///< By-reference - kParameterDirection_ConstRef, ///< By-const-reference -}; + enum class FunctionDifferentiableLevel + { + None, + Forward, + Backward + }; -void printDiagnosticArg(StringBuilder& sb, ParameterDirection direction); + /// Represents a markup (documentation) associated with a decl. + FIDDLE() + class MarkupEntry : public RefObject + { + FIDDLE(...) + NodeBase* m_node; ///< The node this documentation is associated with + String m_markup; ///< The raw contents of of markup associated with the decoration + MarkupVisibility m_visibility = MarkupVisibility::Public; ///< How visible this decl is + }; -/// The kind of a builtin interface requirement that can be automatically synthesized. -enum class BuiltinRequirementKind -{ - DefaultInitializableConstructor, ///< The `IDefaultInitializable.__init()` method - - DifferentialType, ///< The `IDifferentiable.Differential` associated type requirement - DifferentialPtrType, ///< The `IDifferentiable.DifferentialPtr` associated type requirement - DZeroFunc, ///< The `IDifferentiable.dzero` function requirement - DAddFunc, ///< The `IDifferentiable.dadd` function requirement - DMulFunc, ///< The `IDifferentiable.dmul` function requirement - - InitLogicalFromInt, ///< The `ILogical.__init` mtehod. - Equals, ///< The `ILogical.equals` mtehod. - LessThan, ///< The `ILogical.lessThan` mtehod. - LessThanOrEquals, ///< The `ILogical.lessThanOrEquals` mtehod. - Shl, ///< The `ILogical.shl` mtehod. - Shr, ///< The `ILogical.shr` mtehod. - BitAnd, ///< The `ILogical.bitAnd` mtehod. - BitOr, ///< The `ILogical.bitOr` mtehod. - BitXor, ///< The `ILogical.bitXor` mtehod. - BitNot, ///< The `ILogical.bitNot` mtehod. - And, ///< The `ILogical.and` mtehod. - Or, ///< The `ILogical.or` mtehod. - Not, ///< The `ILogical.not` mtehod. -}; - -enum class FunctionDifferentiableLevel -{ - None, - Forward, - Backward -}; - -/// Represents a markup (documentation) associated with a decl. -FIDDLE() -class MarkupEntry : public RefObject -{ - FIDDLE(...) - NodeBase* m_node; ///< The node this documentation is associated with - String m_markup; ///< The raw contents of of markup associated with the decoration - MarkupVisibility m_visibility = MarkupVisibility::Public; ///< How visible this decl is -}; - -/// Get the inner most expr from an higher order expr chain, e.g. `__fwd_diff(__fwd_diff(f))`'s -/// inner most expr is `f`. -Expr* getInnerMostExprFromHigherOrderExpr(Expr* expr, FunctionDifferentiableLevel& outDiffLevel); -inline Expr* getInnerMostExprFromHigherOrderExpr(Expr* expr) -{ - FunctionDifferentiableLevel level; - return getInnerMostExprFromHigherOrderExpr(expr, level); -} + /// Get the inner most expr from an higher order expr chain, e.g. `__fwd_diff(__fwd_diff(f))`'s + /// inner most expr is `f`. + Expr* getInnerMostExprFromHigherOrderExpr( + Expr * expr, + FunctionDifferentiableLevel & outDiffLevel); + inline Expr* getInnerMostExprFromHigherOrderExpr(Expr * expr) + { + FunctionDifferentiableLevel level; + return getInnerMostExprFromHigherOrderExpr(expr, level); + } -/// Get the operator name from the higher order invoke expr. -UnownedStringSlice getHigherOrderOperatorName(HigherOrderInvokeExpr* expr); + /// Get the operator name from the higher order invoke expr. + UnownedStringSlice getHigherOrderOperatorName(HigherOrderInvokeExpr * expr); -enum class DeclVisibility -{ - Private, - Internal, - Public, - Default = Internal, -}; + enum class DeclVisibility + { + Private, + Internal, + Public, + Default = Internal, + }; } // namespace Slang diff --git a/source/slang/slang-ast-type.cpp b/source/slang/slang-ast-type.cpp index 107543d035a..ff4cc0d100e 100644 --- a/source/slang/slang-ast-type.cpp +++ b/source/slang/slang-ast-type.cpp @@ -2,8 +2,8 @@ #include "slang-ast-type.h" #include "slang-ast-builder.h" -#include "slang-ast-modifier.h" #include "slang-ast-dispatch.h" +#include "slang-ast-modifier.h" #include "slang-syntax.h" #include diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp index 7aef966edab..efb87b83154 100644 --- a/source/slang/slang-ast-val.cpp +++ b/source/slang/slang-ast-val.cpp @@ -2,9 +2,9 @@ #include "slang-ast-val.h" #include "slang-ast-builder.h" +#include "slang-ast-dispatch.h" #include "slang-check-impl.h" #include "slang-diagnostics.h" -#include "slang-ast-dispatch.h" #include "slang-mangle.h" #include "slang-syntax.h" diff --git a/source/slang/slang-ast-val.h b/source/slang/slang-ast-val.h index 6ee42c30b51..cdfb0b51fb2 100644 --- a/source/slang/slang-ast-val.h +++ b/source/slang/slang-ast-val.h @@ -3,7 +3,6 @@ #include "slang-ast-base.h" #include "slang-ast-decl.h" - #include "slang-ast-val.h.fiddle" FIDDLE() diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 251dfdc7947..e511fbc39c2 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -12,8 +12,8 @@ // logic also orchestrates the overall flow and how // and when things get checked. -#include "slang-ast-iterator.h" #include "slang-ast-forward-declarations.h" +#include "slang-ast-iterator.h" #include "slang-ast-synthesis.h" #include "slang-lookup.h" #include "slang-parser.h" diff --git a/source/slang/slang-check-resolve-val.cpp b/source/slang/slang-check-resolve-val.cpp index 4a95fe9d864..e16a470de9d 100644 --- a/source/slang/slang-check-resolve-val.cpp +++ b/source/slang/slang-check-resolve-val.cpp @@ -2,12 +2,12 @@ // Logic for resolving/simplifying Types and DeclRefs. +#include "slang-ast-dispatch.h" #include "slang-ast-forward-declarations.h" #include "slang-ast-synthesis.h" #include "slang-check-impl.h" #include "slang-lookup.h" #include "slang-syntax.h" -#include "slang-ast-dispatch.h" namespace Slang { diff --git a/source/slang/slang-check-type.cpp b/source/slang/slang-check-type.cpp index 6edc2191c3b..db753713bb3 100644 --- a/source/slang/slang-check-type.cpp +++ b/source/slang/slang-check-type.cpp @@ -266,7 +266,10 @@ bool SemanticsVisitor::CoerceToProperTypeImpl( // diagnostic. // Get the AST node type info, so we can output a 'got' name - diagSink->diagnose(originalExpr, Diagnostics::expectedAType, originalExpr->getClass().getName()); + diagSink->diagnose( + originalExpr, + Diagnostics::expectedAType, + originalExpr->getClass().getName()); } } diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 6d80b9f2311..8f95011049c 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -2172,8 +2172,7 @@ SlangResult EndToEndCompileRequest::writeContainerToStream(Stream* stream) options.sourceManager = linkage->getSourceManager(); } - SLANG_RETURN_ON_FAIL( - SerialContainerUtil::write(this, options, stream)); + SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(this, options, stream)); return SLANG_OK; } diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp index 35c920707d1..42f18977662 100644 --- a/source/slang/slang-module-library.cpp +++ b/source/slang/slang-module-library.cpp @@ -62,9 +62,7 @@ SlangResult loadModuleLibrary( for (auto moduleChunk : container.getModules()) { - auto loadedModule = linkage->findOrLoadSerializedModuleForModuleLibrary( - moduleChunk, - sink); + auto loadedModule = linkage->findOrLoadSerializedModuleForModuleLibrary(moduleChunk, sink); if (!loadedModule) return SLANG_FAIL; diff --git a/source/slang/slang-parser.h b/source/slang/slang-parser.h index b5c8e4a1fc8..c4e68a7faef 100644 --- a/source/slang/slang-parser.h +++ b/source/slang/slang-parser.h @@ -45,8 +45,8 @@ ModuleDecl* populateBaseLanguageModule(ASTBuilder* astBuilder, Scope* scope); /// for the `parseUserData` to be set the the associated classInfo struct SyntaxParseInfo { - const char* keywordName; ///< The keyword associated with this parse - SyntaxParseCallback callback; ///< The callback to apply to the parse + const char* keywordName; ///< The keyword associated with this parse + SyntaxParseCallback callback; ///< The callback to apply to the parse SyntaxClass classInfo; ///< }; diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp index 3ba79ce1cac..872f13575b1 100644 --- a/source/slang/slang-serialize-ast.cpp +++ b/source/slang/slang-serialize-ast.cpp @@ -2,350 +2,335 @@ #include "slang-serialize-ast.h" #include "slang-ast-dispatch.h" - #include "slang-compiler.h" #include "slang-diagnostics.h" #include "slang-mangle.h" namespace Slang { - // TODO(tfoley): have the parser export this, or a utility function - // for initializing a `SyntaxDecl` in the common case. - // - NodeBase* parseSimpleSyntax(Parser* parser, void* userData); +// TODO(tfoley): have the parser export this, or a utility function +// for initializing a `SyntaxDecl` in the common case. +// +NodeBase* parseSimpleSyntax(Parser* parser, void* userData); - struct ASTEncodingContext +struct ASTEncodingContext +{ +private: + Encoder* encoder; + struct UnhandledCase { - private: - Encoder* encoder; - struct UnhandledCase {}; + }; - typedef Int DeclID; - Dictionary mapDeclToID; - List decls; + typedef Int DeclID; + Dictionary mapDeclToID; + List decls; - struct ImportedDeclInfo - { - Int moduleIndex = -1; - Decl* decl; - }; - List importedDecls; + struct ImportedDeclInfo + { + Int moduleIndex = -1; + Decl* decl; + }; + List importedDecls; - typedef Int ValID; - Dictionary mapValToID; - List vals; + typedef Int ValID; + Dictionary mapValToID; + List vals; - ModuleDecl* _module = nullptr; + ModuleDecl* _module = nullptr; - SerialSourceLocWriter* _sourceLocWriter = nullptr; + SerialSourceLocWriter* _sourceLocWriter = nullptr; - public: - ASTEncodingContext( - Encoder* encoder, - ModuleDecl* module, - SerialSourceLocWriter* sourceLocWriter) - : encoder(encoder) - , _module(module) - , _sourceLocWriter(sourceLocWriter) - {} +public: + ASTEncodingContext(Encoder* encoder, ModuleDecl* module, SerialSourceLocWriter* sourceLocWriter) + : encoder(encoder), _module(module), _sourceLocWriter(sourceLocWriter) + { + } - template - void encodeASTNodeContent(T* node) - { - Encoder::WithObject withObject(encoder); + template + void encodeASTNodeContent(T* node) + { + Encoder::WithObject withObject(encoder); - ASTNodeDispatcher::dispatch(node, [&](auto n) - { - _encodeDataOf(n); - }); - } + ASTNodeDispatcher::dispatch(node, [&](auto n) { _encodeDataOf(n); }); + } - void flush() + void flush() + { + auto containerChunk = encoder->getRIFFChunk(); + + RiffContainer::Chunk* declChunk = nullptr; + RiffContainer::Chunk* importedDeclChunk = nullptr; + RiffContainer::Chunk* valChunk = nullptr; + { + Encoder::WithArray withList(encoder); + declChunk = encoder->getRIFFChunk(); + } { - auto containerChunk = encoder->getRIFFChunk(); + Encoder::WithArray withList(encoder); + importedDeclChunk = encoder->getRIFFChunk(); + } + { + Encoder::WithArray withList(encoder); + valChunk = encoder->getRIFFChunk(); + } + Int declIndex = 0; + Int importedDeclIndex = 0; + Int valIndex = 0; - RiffContainer::Chunk* declChunk = nullptr; - RiffContainer::Chunk* importedDeclChunk = nullptr; - RiffContainer::Chunk* valChunk = nullptr; + bool done = false; + do + { + done = true; + while (declIndex < decls.getCount()) { - Encoder::WithArray withList(encoder); - declChunk = encoder->getRIFFChunk(); + done = false; + encoder->setRIFFChunk(declChunk); + encodeASTNodeContent(decls[declIndex++]); } + while (importedDeclIndex < importedDecls.getCount()) { - Encoder::WithArray withList(encoder); - importedDeclChunk = encoder->getRIFFChunk(); + done = false; + encoder->setRIFFChunk(importedDeclChunk); + encodeImportedDecl(importedDecls[importedDeclIndex++]); } + while (valIndex < vals.getCount()) { - Encoder::WithArray withList(encoder); - valChunk = encoder->getRIFFChunk(); + done = false; + encoder->setRIFFChunk(valChunk); + encodeASTNodeContent(vals[valIndex++]); } - Int declIndex = 0; - Int importedDeclIndex = 0; - Int valIndex = 0; - - bool done = false; - do - { - done = true; - while (declIndex < decls.getCount()) - { - done = false; - encoder->setRIFFChunk(declChunk); - encodeASTNodeContent(decls[declIndex++]); - } - while (importedDeclIndex < importedDecls.getCount()) - { - done = false; - encoder->setRIFFChunk(importedDeclChunk); - encodeImportedDecl(importedDecls[importedDeclIndex++]); - } - while (valIndex < vals.getCount()) - { - done = false; - encoder->setRIFFChunk(valChunk); - encodeASTNodeContent(vals[valIndex++]); - } - } while (!done); + } while (!done); - RiffContainer::calcAndSetSize(containerChunk); - encoder->setRIFFChunk(containerChunk); - } + RiffContainer::calcAndSetSize(containerChunk); + encoder->setRIFFChunk(containerChunk); + } - ModuleDecl* findModuleForDecl(Decl* decl) + ModuleDecl* findModuleForDecl(Decl* decl) + { + for (auto d = decl; d; d = d->parentDecl) { - for (auto d = decl; d; d = d->parentDecl) - { - if (auto m = as(d)) - return m; - } - return nullptr; + if (auto m = as(d)) + return m; } + return nullptr; + } - ModuleDecl* findModuleDeclWasImportedFrom(Decl* decl) - { - auto declModule = findModuleForDecl(decl); - if (declModule == nullptr) - return nullptr; - if (declModule == _module) - return nullptr; - return declModule; - } + ModuleDecl* findModuleDeclWasImportedFrom(Decl* decl) + { + auto declModule = findModuleForDecl(decl); + if (declModule == nullptr) + return nullptr; + if (declModule == _module) + return nullptr; + return declModule; + } - DeclID getDeclID(Decl* decl) - { - SLANG_ASSERT(decl != nullptr); + DeclID getDeclID(Decl* decl) + { + SLANG_ASSERT(decl != nullptr); - if (auto found = mapDeclToID.tryGetValue(decl)) - return *found; + if (auto found = mapDeclToID.tryGetValue(decl)) + return *found; - // We need to detect whether the declaration is an - // imported one, or one from this module itself. - // - // Imported declarations need to be handled very - // differently, since they'll involve resolving - // references to those other modules, and the - // declarations within them. - // - if(auto importedFromModule = findModuleDeclWasImportedFrom(decl)) + // We need to detect whether the declaration is an + // imported one, or one from this module itself. + // + // Imported declarations need to be handled very + // differently, since they'll involve resolving + // references to those other modules, and the + // declarations within them. + // + if (auto importedFromModule = findModuleDeclWasImportedFrom(decl)) + { + DeclID importedFromModuleDeclID = 0; + if (decl != importedFromModule) { - DeclID importedFromModuleDeclID = 0; - if (decl != importedFromModule) - { - importedFromModuleDeclID = getDeclID(importedFromModule); - } - - DeclID id = ~importedDecls.getCount(); - mapDeclToID.add(decl, id); + importedFromModuleDeclID = getDeclID(importedFromModule); + } - ImportedDeclInfo info; - info.moduleIndex = ~importedFromModuleDeclID; - info.decl = decl; - importedDecls.add(info); + DeclID id = ~importedDecls.getCount(); + mapDeclToID.add(decl, id); - return id; - } - else - { - DeclID id = decls.getCount(); - decls.add(decl); - mapDeclToID.add(decl, id); + ImportedDeclInfo info; + info.moduleIndex = ~importedFromModuleDeclID; + info.decl = decl; + importedDecls.add(info); - return id; - } + return id; } - - void encodePtr(Decl* decl) + else { - DeclID id = getDeclID(decl); - encoder->encode(id); + DeclID id = decls.getCount(); + decls.add(decl); + mapDeclToID.add(decl, id); + + return id; } + } - ValID getValID(Val* val) - { - SLANG_ASSERT(val != nullptr); + void encodePtr(Decl* decl) + { + DeclID id = getDeclID(decl); + encoder->encode(id); + } + + ValID getValID(Val* val) + { + SLANG_ASSERT(val != nullptr); - if (auto found = mapValToID.tryGetValue(val)) - return *found; + if (auto found = mapValToID.tryGetValue(val)) + return *found; - // In order to ensure that values can be fully constructed - // from the get-go (so that they will get cached correctly), - // we conspire to ensure that every value is preceded by - // all of its operands. - // - for (auto operand : val->m_operands) + // In order to ensure that values can be fully constructed + // from the get-go (so that they will get cached correctly), + // we conspire to ensure that every value is preceded by + // all of its operands. + // + for (auto operand : val->m_operands) + { + switch (operand.kind) { - switch (operand.kind) + default: + break; + + case ValNodeOperandKind::ValNode: + if (auto operandNode = operand.values.nodeOperand) { - default: - break; - - case ValNodeOperandKind::ValNode: - if (auto operandNode = operand.values.nodeOperand) - { - SLANG_ASSERT(as(operandNode)); - getValID(static_cast(operandNode)); - } - break; - - case ValNodeOperandKind::ASTNode: - if (auto operandNode = operand.values.nodeOperand) - { - SLANG_ASSERT(as(operandNode)); - getDeclID(static_cast(operandNode)); - } - break; + SLANG_ASSERT(as(operandNode)); + getValID(static_cast(operandNode)); } - } - auto resolved = val->resolve(); - if (resolved != val) - { - getValID(resolved); - } + break; - ValID id = vals.getCount(); - vals.add(val); - mapValToID.add(val, id); - return id; + case ValNodeOperandKind::ASTNode: + if (auto operandNode = operand.values.nodeOperand) + { + SLANG_ASSERT(as(operandNode)); + getDeclID(static_cast(operandNode)); + } + break; + } } - - void encodePtr(Val* val) + auto resolved = val->resolve(); + if (resolved != val) { - ValID id = getValID(val); - encoder->encode(id); + getValID(resolved); } - void encodeImportedDecl(ImportedDeclInfo const& info) - { - Encoder::WithKeyValuePair withPair(encoder); - encode(info.moduleIndex); - auto decl = info.decl; - if (auto importedModuleDecl = as(decl)) - { - SLANG_ASSERT(info.moduleIndex == -1); - encode(importedModuleDecl->getName()); - } - else - { - auto mangledName = getMangledName(getCurrentASTBuilder(), decl); - encode(mangledName); - } - } + ValID id = vals.getCount(); + vals.add(val); + mapValToID.add(val, id); + return id; + } - void encodePtr(Modifier* modifier) { encodeASTNodeContent(modifier); } - void encodePtr(Expr* expr) { encodeASTNodeContent(expr); } - void encodePtr(Stmt* stmt) { encodeASTNodeContent(stmt); } + void encodePtr(Val* val) + { + ValID id = getValID(val); + encoder->encode(id); + } - void encodePtr(Name* name) + void encodeImportedDecl(ImportedDeclInfo const& info) + { + Encoder::WithKeyValuePair withPair(encoder); + encode(info.moduleIndex); + auto decl = info.decl; + if (auto importedModuleDecl = as(decl)) { - encode(name->text); + SLANG_ASSERT(info.moduleIndex == -1); + encode(importedModuleDecl->getName()); } - - void encodePtr(MarkupEntry* entry) + else { - // TODO: is this case needed? - SLANG_UNUSED(entry); + auto mangledName = getMangledName(getCurrentASTBuilder(), decl); + encode(mangledName); } + } - void encodePtr(DeclAssociationList* list) - { - // We serialize this as if it were a simple list - // of key-value pairs because... well... that's - // what it amounts to in practice. - // - Encoder::WithArray withArray(encoder); - for (auto association : list->associations) - { - Encoder::WithKeyValuePair withPair(encoder); - encode(association->kind); - encode(association->decl); - } - } + void encodePtr(Modifier* modifier) { encodeASTNodeContent(modifier); } + void encodePtr(Expr* expr) { encodeASTNodeContent(expr); } + void encodePtr(Stmt* stmt) { encodeASTNodeContent(stmt); } + + void encodePtr(Name* name) { encode(name->text); } + + void encodePtr(MarkupEntry* entry) + { + // TODO: is this case needed? + SLANG_UNUSED(entry); + } - void encodePtr(CandidateExtensionList* list) + void encodePtr(DeclAssociationList* list) + { + // We serialize this as if it were a simple list + // of key-value pairs because... well... that's + // what it amounts to in practice. + // + Encoder::WithArray withArray(encoder); + for (auto association : list->associations) { - encode(list->candidateExtensions); + Encoder::WithKeyValuePair withPair(encoder); + encode(association->kind); + encode(association->decl); } + } - void encodePtr(WitnessTable* witnessTable) - { - Encoder::WithObject withObject(encoder); - encode(witnessTable->baseType); - encode(witnessTable->witnessedType); - encode(witnessTable->isExtern); + void encodePtr(CandidateExtensionList* list) { encode(list->candidateExtensions); } - // TODO(tfoley): In theory we should be able to streamline - // this so that we only encode the requirements that we - // absolutely need to (which basically amounts to `associatedtype` - // requirements where the satisfying type is part of the public - // API of the type). - // - encode(witnessTable->m_requirementDictionary); - } + void encodePtr(WitnessTable* witnessTable) + { + Encoder::WithObject withObject(encoder); + encode(witnessTable->baseType); + encode(witnessTable->witnessedType); + encode(witnessTable->isExtern); + + // TODO(tfoley): In theory we should be able to streamline + // this so that we only encode the requirements that we + // absolutely need to (which basically amounts to `associatedtype` + // requirements where the satisfying type is part of the public + // API of the type). + // + encode(witnessTable->m_requirementDictionary); + } - void encodeValue(RequirementWitness const& witness) + void encodeValue(RequirementWitness const& witness) + { + Encoder::WithKeyValuePair withPair(encoder); + encodeEnum(witness.m_flavor); + switch (witness.m_flavor) { - Encoder::WithKeyValuePair withPair(encoder); - encodeEnum(witness.m_flavor); - switch (witness.m_flavor) - { - case RequirementWitness::Flavor::none: - break; + case RequirementWitness::Flavor::none: + break; - case RequirementWitness::Flavor::declRef: - encode(witness.m_declRef); - break; + case RequirementWitness::Flavor::declRef: + encode(witness.m_declRef); + break; - case RequirementWitness::Flavor::val: - encode(witness.m_val); - break; + case RequirementWitness::Flavor::val: + encode(witness.m_val); + break; - case RequirementWitness::Flavor::witnessTable: - encode((WitnessTable*) witness.m_obj.Ptr()); - break; - } + case RequirementWitness::Flavor::witnessTable: + encode((WitnessTable*)witness.m_obj.Ptr()); + break; } + } - void encodePtr(DiagnosticInfo* info) { encode(Int(info->id)); } + void encodePtr(DiagnosticInfo* info) { encode(Int(info->id)); } - void encodePtr(DeclBase* declBase) + void encodePtr(DeclBase* declBase) + { + if (auto decl = as(declBase)) { - if (auto decl = as(declBase)) - { - encodePtr(decl); - } - else - { - encodeASTNodeContent(declBase); - } + encodePtr(decl); + } + else + { + encodeASTNodeContent(declBase); } + } void encodeValue(UnhandledCase); - void encodeValue(String const& value) - { - encoder->encode(value); - } + void encodeValue(String const& value) { encoder->encode(value); } void encodeValue(Token const& value) { @@ -358,15 +343,9 @@ namespace Slang encode(nullptr); } - void encodeValue(NameLoc const& value) - { - encode(value.name); - } + void encodeValue(NameLoc const& value) { encode(value.name); } - void encodeValue(SemanticVersion value) - { - encoder->encode(value.toInteger()); - } + void encodeValue(SemanticVersion value) { encoder->encode(value.toInteger()); } void encodeValue(CapabilitySet const& value) { @@ -423,15 +402,12 @@ namespace Slang encoder->encode(nullptr); } - void encodeValue(SyntaxClass const& value) - { - encode(value.getTag()); - } + void encodeValue(SyntaxClass const& value) { encode(value.getTag()); } template void encodeValue(DeclRef const& value) { - encode((DeclRefBase*) value); + encode((DeclRefBase*)value); } void encodeValue(ValNodeOperand value) @@ -450,24 +426,21 @@ namespace Slang break; case ValNodeOperandKind::ASTNode: - { - if (auto decl = as(value.values.nodeOperand)) - { - encode(decl); - } - else { - SLANG_UNEXPECTED("AST node operand of `Val` was expected to be a `Decl`"); + if (auto decl = as(value.values.nodeOperand)) + { + encode(decl); + } + else + { + SLANG_UNEXPECTED("AST node operand of `Val` was expected to be a `Decl`"); + } } - } - break; + break; } } - void encodeValue(TypeExp value) - { - encode(value.type); - } + void encodeValue(TypeExp value) { encode(value.type); } void encodeValue(QualType value) { @@ -485,10 +458,7 @@ namespace Slang encode(value.col); } - void encodeValue(SPIRVAsmOperand::Flavor const& value) - { - encodeEnum(value); - } + void encodeValue(SPIRVAsmOperand::Flavor const& value) { encodeEnum(value); } void encodeValue(SPIRVAsmOperand const& value) { @@ -510,9 +480,11 @@ namespace Slang } - template>> - void encodeValue(T value) { encoder->encodeBool(value); } + void encodeValue(T value) + { + encoder->encodeBool(value); + } void encodeValue(Int32 value) { encoder->encode(value); } void encodeValue(UInt32 value) { encoder->encode(value); } @@ -521,15 +493,9 @@ namespace Slang void encodeValue(float value) { encoder->encode(value); } void encodeValue(double value) { encoder->encode(value); } - void encodeValue(uint8_t value) - { - encoder->encode(UInt32(value)); - } + void encodeValue(uint8_t value) { encoder->encode(UInt32(value)); } - void encodeValue(nullptr_t) - { - encoder->encode(nullptr); - } + void encodeValue(nullptr_t) { encoder->encode(nullptr); } template void encodeEnum(T value) @@ -618,7 +584,7 @@ namespace Slang } template - void encode(T const (&array)[N] ) + void encode(T const (&array)[N]) { Encoder::WithArray withArray(encoder); for (auto element : array) @@ -677,866 +643,864 @@ namespace Slang #define FIDDLE_GENERATED_OUTPUT_ID 0 #include "slang-serialize-ast.cpp.fiddle" #endif // FIDDLE END - }; +}; + +void writeSerializedModuleAST( + Encoder* encoder, + ModuleDecl* moduleDecl, + SerialSourceLocWriter* sourceLocWriter) +{ + Encoder::WithObject withObject(encoder); + + // TODO: we should have a more careful pass here, + // where we only encode the public declarations + // + + ASTEncodingContext context(encoder, moduleDecl, sourceLocWriter); + context.getDeclID(moduleDecl); + context.flush(); +} + +struct ASTDecodingContext +{ +public: + ASTDecodingContext( + Linkage* linkage, + ASTBuilder* astBuilder, + DiagnosticSink* sink, + RiffContainer::Chunk* rootChunk, + SerialSourceLocReader* sourceLocReader, + SourceLoc requestingSourceLoc) + : _linkage(linkage) + , _astBuilder(astBuilder) + , _sink(sink) + , _rootChunk(static_cast(rootChunk)) + , _sourceLocReader(sourceLocReader) + , _requestingSourceLoc(requestingSourceLoc) + { + } - void writeSerializedModuleAST( - Encoder* encoder, - ModuleDecl* moduleDecl, - SerialSourceLocWriter* sourceLocWriter) + Linkage* _linkage = nullptr; + DiagnosticSink* _sink = nullptr; + SerialSourceLocReader* _sourceLocReader = nullptr; + SourceLoc _requestingSourceLoc; + + SlangResult decodeAll() { - Encoder::WithObject withObject(encoder); + auto cursor = _rootChunk->getFirstContainedChunk(); - // TODO: we should have a more careful pass here, - // where we only encode the public declarations + // There are a few different top-level chunks that + // hold different arrays that we need in order + // to decode the entire module hierarchy. + // + // Basically, these lists correspond to the kinds + // of nodes in the AST hierarchy for which back-references + // are allowed (all other nodes should, barring + // weird corner cases, form a single tree-structured + // ownership hierarchy, rooted at the `ModuleDecl`. // - ASTEncodingContext context(encoder, moduleDecl, sourceLocWriter); - context.getDeclID(moduleDecl); - context.flush(); - } - - struct ASTDecodingContext - { - public: - ASTDecodingContext( - Linkage* linkage, - ASTBuilder* astBuilder, - DiagnosticSink* sink, - RiffContainer::Chunk* rootChunk, - SerialSourceLocReader* sourceLocReader, - SourceLoc requestingSourceLoc) - : _linkage(linkage) - , _astBuilder(astBuilder) - , _sink(sink) - , _rootChunk(static_cast(rootChunk)) - , _sourceLocReader(sourceLocReader) - , _requestingSourceLoc(requestingSourceLoc) - {} - - Linkage* _linkage = nullptr; - DiagnosticSink* _sink = nullptr; - SerialSourceLocReader* _sourceLocReader = nullptr; - SourceLoc _requestingSourceLoc; - - SlangResult decodeAll() - { - auto cursor = _rootChunk->getFirstContainedChunk(); - - // There are a few different top-level chunks that - // hold different arrays that we need in order - // to decode the entire module hierarchy. - // - // Basically, these lists correspond to the kinds - // of nodes in the AST hierarchy for which back-references - // are allowed (all other nodes should, barring - // weird corner cases, form a single tree-structured - // ownership hierarchy, rooted at the `ModuleDecl`. - // + // First there is the list that actually encodes + // for the declarations in the module, including + // the `ModuleDecl` itself, which should be the + // first entry in the list. + // + auto declChunk = cursor; + cursor = cursor->m_next; - // First there is the list that actually encodes - // for the declarations in the module, including - // the `ModuleDecl` itself, which should be the - // first entry in the list. - // - auto declChunk = cursor; - cursor = cursor->m_next; + // Next there is a list of all the declarations + // referenced inside of the module that need to + // be imported in from outside. + // + auto importedDeclChunk = cursor; + cursor = cursor->m_next; - // Next there is a list of all the declarations - // referenced inside of the module that need to - // be imported in from outside. - // - auto importedDeclChunk = cursor; - cursor = cursor->m_next; + // Then there are all the `Val`-derived nodes that + // are needed by the module, which will need to be + // deduplicated so that they are unique within the + // current compilation context. + // + auto valChunk = cursor; + cursor = cursor->m_next; - // Then there are all the `Val`-derived nodes that - // are needed by the module, which will need to be - // deduplicated so that they are unique within the - // current compilation context. - // - auto valChunk = cursor; - cursor = cursor->m_next; + // The process of decoding the module is then spread + // over a number of steps. + // + // The first step is to process all of the imported + // declarations, so that other nodes can refer to + // them. + // + SLANG_RETURN_ON_FAIL(decodeImportedDecls(importedDeclChunk)); + + // Next we process the declarations that are within + // the module itself, first creating an "empty shell" + // of each declaration that has the right size in + // memory (and the right `ASTNodeType` tag), so that + // we can wire up references to it (including circular + // references)... so long as nothing here tries to + // look *inside* the empty shell along the way. + // + SLANG_RETURN_ON_FAIL(createEmptyShells(declChunk)); - // The process of decoding the module is then spread - // over a number of steps. - // - // The first step is to process all of the imported - // declarations, so that other nodes can refer to - // them. - // - SLANG_RETURN_ON_FAIL(decodeImportedDecls(importedDeclChunk)); - - // Next we process the declarations that are within - // the module itself, first creating an "empty shell" - // of each declaration that has the right size in - // memory (and the right `ASTNodeType` tag), so that - // we can wire up references to it (including circular - // references)... so long as nothing here tries to - // look *inside* the empty shell along the way. - // - SLANG_RETURN_ON_FAIL(createEmptyShells(declChunk)); + // Once all the `Decl`s that might be needed have + // been allocated, we can process all the `Val`s + // that might reference those`Decl`s (and one another). + // + // The nature of the `Val` representation ensures + // that there cannot be cirularities in the references + // between `Val`s, and the encoding process will have + // sorted the entries so that a `Val` only ever appears + // *after* its operands. + // + SLANG_RETURN_ON_FAIL(decodeVals(valChunk)); - // Once all the `Decl`s that might be needed have - // been allocated, we can process all the `Val`s - // that might reference those`Decl`s (and one another). - // - // The nature of the `Val` representation ensures - // that there cannot be cirularities in the references - // between `Val`s, and the encoding process will have - // sorted the entries so that a `Val` only ever appears - // *after* its operands. - // - SLANG_RETURN_ON_FAIL(decodeVals(valChunk)); + // Once all the back-reference-able objects have been + // instantiated in memory, we can go back through the + // `Decl`s in the module and fill in those empty shells. + // + SLANG_RETURN_ON_FAIL(fillEmptyShells(declChunk)); - // Once all the back-reference-able objects have been - // instantiated in memory, we can go back through the - // `Decl`s in the module and fill in those empty shells. - // - SLANG_RETURN_ON_FAIL(fillEmptyShells(declChunk)); + // As a final pass, we perform any special cleanup actions + // that might be required to make the output valid for consumers. + // + // For example, this is where we set the `DeclCheckState` of everything + // we are loading to reflect the fact that everything we deserialize + // is (supposed to be) fully cheked. + // + SLANG_RETURN_ON_FAIL(cleanUpNodes()); - // As a final pass, we perform any special cleanup actions - // that might be required to make the output valid for consumers. - // - // For example, this is where we set the `DeclCheckState` of everything - // we are loading to reflect the fact that everything we deserialize - // is (supposed to be) fully cheked. - // - SLANG_RETURN_ON_FAIL(cleanUpNodes()); + return SLANG_OK; + } - return SLANG_OK; + typedef Int DeclID; + Decl* getDeclByID(DeclID id) + { + if (id >= 0) + { + return _decls[id]; + } + else + { + return _importedDecls[~id]; } + } + +private: + struct UnhandledCase + { + }; + + ASTBuilder* _astBuilder = nullptr; + RiffContainer::ListChunk* _rootChunk = nullptr; + + List _decls; + List _importedDecls; + List _vals; + + typedef Int ValID; + Val* getValByID(ValID id) { return _vals[id]; } - typedef Int DeclID; - Decl* getDeclByID(DeclID id) + SlangResult decodeImportedDecls(RiffContainer::Chunk* importedDeclChunk) + { + Decoder decoder(importedDeclChunk); + + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - if (id >= 0) + Decoder::WithKeyValuePair withPair(decoder); + + Int moduleIndex; + decode(moduleIndex, decoder); + + if (moduleIndex == -1) { - return _decls[id]; + Name* moduleName = nullptr; + decode(moduleName, decoder); + + Decl* importedModule = getImportedModule(moduleName); + _importedDecls.add(importedModule); } else { - return _importedDecls[~id]; + auto importedFromModuleDecl = as(_importedDecls[moduleIndex]); + auto importedFromModule = importedFromModuleDecl->module; + + String mangledName; + decode(mangledName, decoder); + + auto importedNode = + importedFromModule->findExportFromMangledName(mangledName.getUnownedSlice()); + auto importedDecl = as(importedNode); + _importedDecls.add(importedDecl); } } + return SLANG_OK; + } - private: - struct UnhandledCase {}; + ModuleDecl* getImportedModule(Name* moduleName) + { + Module* module = _linkage->findOrImportModule(moduleName, _requestingSourceLoc, _sink); + if (!module) + { + SLANG_ABORT_COMPILATION("failed to load an imported module during deserialization"); + } - ASTBuilder* _astBuilder = nullptr; - RiffContainer::ListChunk* _rootChunk = nullptr; + return module->getModuleDecl(); + } - List _decls; - List _importedDecls; - List _vals; + SlangResult decodeVals(RiffContainer::Chunk* valChunk) + { + Decoder decoder(valChunk); - typedef Int ValID; - Val* getValByID(ValID id) + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - return _vals[id]; + Val* val = decodeValNode(decoder); + _vals.add(val); } + return SLANG_OK; + } + + SlangResult createEmptyShells(RiffContainer::Chunk* declChunk) + { + Decoder decoder(declChunk); - SlangResult decodeImportedDecls(RiffContainer::Chunk* importedDeclChunk) + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder decoder(importedDeclChunk); + ASTNodeType nodeType; - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) + // Each of the declarations is expected to take + // the form of an object with a first field + // that holds the node type. + // { - Decoder::WithKeyValuePair withPair(decoder); - - Int moduleIndex; - decode(moduleIndex, decoder); - - if (moduleIndex == -1) - { - Name* moduleName = nullptr; - decode(moduleName, decoder); - - Decl* importedModule = getImportedModule(moduleName); - _importedDecls.add(importedModule); - } - else - { - auto importedFromModuleDecl = as(_importedDecls[moduleIndex]); - auto importedFromModule = importedFromModuleDecl->module; - - String mangledName; - decode(mangledName, decoder); - - auto importedNode = importedFromModule->findExportFromMangledName(mangledName.getUnownedSlice()); - auto importedDecl = as(importedNode); - _importedDecls.add(importedDecl); - } - } - return SLANG_OK; - } - - ModuleDecl* getImportedModule(Name* moduleName) - { - Module* module = _linkage->findOrImportModule( - moduleName, - _requestingSourceLoc, - _sink); - if (!module) - { - SLANG_ABORT_COMPILATION("failed to load an imported module during deserialization"); + Decoder::WithObject withObject(decoder); + decode(nodeType, decoder); } - return module->getModuleDecl(); - } - - SlangResult decodeVals(RiffContainer::Chunk* valChunk) - { - Decoder decoder(valChunk); - - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - Val* val = decodeValNode(decoder); - _vals.add(val); - } - return SLANG_OK; + auto emptyShell = createEmptyShell(nodeType); + auto declEmptyShell = as(emptyShell); + _decls.add(declEmptyShell); } - SlangResult createEmptyShells(RiffContainer::Chunk* declChunk) - { - Decoder decoder(declChunk); - - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - ASTNodeType nodeType; + return SLANG_OK; + } - // Each of the declarations is expected to take - // the form of an object with a first field - // that holds the node type. - // - { - Decoder::WithObject withObject(decoder); - decode(nodeType, decoder); - } + Val* decodeValNode(Decoder& decoder) + { + Decoder::WithObject withObject(decoder); - auto emptyShell = createEmptyShell(nodeType); - auto declEmptyShell = as(emptyShell); - _decls.add(declEmptyShell); - } + ASTNodeType nodeType; + decode(nodeType, decoder); - return SLANG_OK; - } + ValNodeDesc desc; + desc.type = SyntaxClass(nodeType); - Val* decodeValNode(Decoder& decoder) + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithObject withObject(decoder); + ValNodeOperand operand; + decode(operand, decoder); + desc.operands.add(operand); + } - ASTNodeType nodeType; - decode(nodeType, decoder); + desc.init(); - ValNodeDesc desc; - desc.type = SyntaxClass(nodeType); + auto val = _astBuilder->_getOrCreateImpl(_Move(desc)); - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - ValNodeOperand operand; - decode(operand, decoder); - desc.operands.add(operand); - } - - desc.init(); + // Values created during deserialization are + // not expected to ever resolve further, because + // they should be coming from fully checked code. + // + // val->resolve(); + // val->_setUnique(); - auto val = _astBuilder->_getOrCreateImpl(_Move(desc)); + return val; + } - // Values created during deserialization are - // not expected to ever resolve further, because - // they should be coming from fully checked code. - // - // val->resolve(); - // val->_setUnique(); + NodeBase* createEmptyShell(ASTNodeType nodeType) + { + return SyntaxClass(nodeType).createInstance(_astBuilder); + } - return val; - } + SlangResult fillEmptyShells(RiffContainer::Chunk* declChunk) + { + Index declIndex = 0; - NodeBase* createEmptyShell(ASTNodeType nodeType) + Decoder decoder(declChunk); + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - return SyntaxClass(nodeType).createInstance(_astBuilder); + auto declEmptyShell = _decls[declIndex++]; + decodeASTNodeContent(declEmptyShell, decoder); } - SlangResult fillEmptyShells(RiffContainer::Chunk* declChunk) + return SLANG_OK; + } + + SlangResult cleanUpNodes() + { + for (auto decl : _decls) { - Index declIndex = 0; + decl->checkState = DeclCheckState::CapabilityChecked; + } - Decoder decoder(declChunk); - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - auto declEmptyShell = _decls[declIndex++]; - decodeASTNodeContent( - declEmptyShell, - decoder); - } + return SLANG_OK; + } - return SLANG_OK; - } - SlangResult cleanUpNodes() + void assignGenericParameterIndices(GenericDecl* genericDecl) + { + int parameterCounter = 0; + for (auto m : genericDecl->members) { - for (auto decl : _decls) + if (auto typeParam = as(m)) { - decl->checkState = DeclCheckState::CapabilityChecked; + typeParam->parameterIndex = parameterCounter++; } - - return SLANG_OK; - } - - - void assignGenericParameterIndices(GenericDecl* genericDecl) - { - int parameterCounter = 0; - for(auto m : genericDecl->members) + else if (auto valParam = as(m)) { - if (auto typeParam = as(m)) - { - typeParam->parameterIndex = parameterCounter++; - } - else if (auto valParam = as(m)) - { - valParam->parameterIndex = parameterCounter++; - } + valParam->parameterIndex = parameterCounter++; } } + } - void cleanUpASTNode(NodeBase* node) + void cleanUpASTNode(NodeBase* node) + { + if (auto expr = as(node)) { - if (auto expr = as(node)) - { - expr->checked = true; - } - else if (auto genericDecl = as(node)) - { - assignGenericParameterIndices(genericDecl); - } - else if (auto syntaxDecl = as(node)) - { - syntaxDecl->parseCallback = &parseSimpleSyntax; - syntaxDecl->parseUserData = (void*)syntaxDecl->syntaxClass.getInfo(); - } - else if (auto namespaceLikeDecl = as(node)) - { - auto declScope = _astBuilder->create(); - declScope->containerDecl = namespaceLikeDecl; - namespaceLikeDecl->ownedScope = declScope; - } + expr->checked = true; } - - void decodeASTNodeContent( - NodeBase* node, - Decoder& decoder) + else if (auto genericDecl = as(node)) { - Decoder::WithObject withObject(decoder); - - ASTNodeDispatcher::dispatch(node, [&](auto n) - { - _decodeDataOf(n, decoder); - }); - - cleanUpASTNode(node); + assignGenericParameterIndices(genericDecl); } - - DeclID decodeDeclID(Decoder& decoder) + else if (auto syntaxDecl = as(node)) { - DeclID result = decoder.decode(); - return result; + syntaxDecl->parseCallback = &parseSimpleSyntax; + syntaxDecl->parseUserData = (void*)syntaxDecl->syntaxClass.getInfo(); } - - ValID decodeValID(Decoder& decoder) + else if (auto namespaceLikeDecl = as(node)) { - ValID result = decoder.decode(); - return result; + auto declScope = _astBuilder->create(); + declScope->containerDecl = namespaceLikeDecl; + namespaceLikeDecl->ownedScope = declScope; } + } - template - void decodeASTNode(T*& node, Decoder& decoder) - { - ASTNodeType nodeType; - auto saved = decoder.getCursor(); - { - Decoder::WithObject withObject(decoder); - decode(nodeType, decoder); - } - decoder.setCursor(saved); + void decodeASTNodeContent(NodeBase* node, Decoder& decoder) + { + Decoder::WithObject withObject(decoder); - auto shell = createEmptyShell(nodeType); - decodeASTNodeContent(shell, decoder); + ASTNodeDispatcher::dispatch( + node, + [&](auto n) { _decodeDataOf(n, decoder); }); - node = as(shell); - } + cleanUpASTNode(node); + } - void decodePtr(Name*& name, Decoder& decoder, Name*) - { - String text; - decode(text, decoder); + DeclID decodeDeclID(Decoder& decoder) + { + DeclID result = decoder.decode(); + return result; + } - name = _astBuilder->getNamePool()->getName(text); - } + ValID decodeValID(Decoder& decoder) + { + ValID result = decoder.decode(); + return result; + } - void decodePtr(DeclAssociationList*& outList, Decoder& decoder, DeclAssociationList*) + template + void decodeASTNode(T*& node, Decoder& decoder) + { + ASTNodeType nodeType; + auto saved = decoder.getCursor(); { - // Mirroring the encoding logic, we decode this - // as a list of key-value pairs. - // - auto list = RefPtr(new DeclAssociationList()); - Decoder::WithArray withArray(decoder); - while(decoder.hasElements()) - { - auto association = RefPtr(new DeclAssociation()); + Decoder::WithObject withObject(decoder); + decode(nodeType, decoder); + } + decoder.setCursor(saved); - Decoder::WithKeyValuePair withPair(decoder); - decode(association->kind, decoder); - decode(association->decl, decoder); + auto shell = createEmptyShell(nodeType); + decodeASTNodeContent(shell, decoder); - list->associations.add(association); - } + node = as(shell); + } - outList = list.detach(); - } + void decodePtr(Name*& name, Decoder& decoder, Name*) + { + String text; + decode(text, decoder); - void decodePtr(DiagnosticInfo const*& info, Decoder& decoder, DiagnosticInfo const*) - { - Int id; - decode(id, decoder); - info = getDiagnosticsLookup()->getDiagnosticById(id); - } + name = _astBuilder->getNamePool()->getName(text); + } - void decodePtr(MarkupEntry*& markupEntry, Decoder&, MarkupEntry*) + void decodePtr(DeclAssociationList*& outList, Decoder& decoder, DeclAssociationList*) + { + // Mirroring the encoding logic, we decode this + // as a list of key-value pairs. + // + auto list = RefPtr(new DeclAssociationList()); + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - // TODO: is this case needed? - markupEntry = nullptr; - } + auto association = RefPtr(new DeclAssociation()); - void decodePtr(CandidateExtensionList*& list, Decoder& decoder, CandidateExtensionList*) - { - auto result = RefPtr(new CandidateExtensionList()); - decode(result->candidateExtensions, decoder); - list = result.detach(); - } + Decoder::WithKeyValuePair withPair(decoder); + decode(association->kind, decoder); + decode(association->decl, decoder); - void decodePtr(WitnessTable*& witnessTable, Decoder& decoder, WitnessTable*) - { - Decoder::WithObject withObject(decoder); - auto wt = RefPtr(new WitnessTable()); - decode(wt->baseType, decoder); - decode(wt->witnessedType, decoder); - decode(wt->isExtern, decoder); - decode(wt->m_requirementDictionary, decoder); - witnessTable = wt.detach(); + list->associations.add(association); } - void decodeValue(RequirementWitness& witness, Decoder& decoder) - { - Decoder::WithKeyValuePair withPair(decoder); - decodeEnum(witness.m_flavor, decoder); - switch (witness.m_flavor) - { - case RequirementWitness::Flavor::none: - break; + outList = list.detach(); + } - case RequirementWitness::Flavor::declRef: - decode(witness.m_declRef, decoder); - break; + void decodePtr(DiagnosticInfo const*& info, Decoder& decoder, DiagnosticInfo const*) + { + Int id; + decode(id, decoder); + info = getDiagnosticsLookup()->getDiagnosticById(id); + } - case RequirementWitness::Flavor::val: - decode(witness.m_val, decoder); - break; + void decodePtr(MarkupEntry*& markupEntry, Decoder&, MarkupEntry*) + { + // TODO: is this case needed? + markupEntry = nullptr; + } - case RequirementWitness::Flavor::witnessTable: - decode(*(RefPtr*)(&witness.m_obj), decoder); - break; - } - } + void decodePtr(CandidateExtensionList*& list, Decoder& decoder, CandidateExtensionList*) + { + auto result = RefPtr(new CandidateExtensionList()); + decode(result->candidateExtensions, decoder); + list = result.detach(); + } - template - void decodePtr(T*& node, Decoder& decoder, Val*) + void decodePtr(WitnessTable*& witnessTable, Decoder& decoder, WitnessTable*) + { + Decoder::WithObject withObject(decoder); + auto wt = RefPtr(new WitnessTable()); + decode(wt->baseType, decoder); + decode(wt->witnessedType, decoder); + decode(wt->isExtern, decoder); + decode(wt->m_requirementDictionary, decoder); + witnessTable = wt.detach(); + } + + void decodeValue(RequirementWitness& witness, Decoder& decoder) + { + Decoder::WithKeyValuePair withPair(decoder); + decodeEnum(witness.m_flavor, decoder); + switch (witness.m_flavor) { - ValID id = decodeValID(decoder); - node = static_cast(getValByID(id)); + case RequirementWitness::Flavor::none: + break; + + case RequirementWitness::Flavor::declRef: + decode(witness.m_declRef, decoder); + break; + + case RequirementWitness::Flavor::val: + decode(witness.m_val, decoder); + break; + + case RequirementWitness::Flavor::witnessTable: + decode(*(RefPtr*)(&witness.m_obj), decoder); + break; } + } + + template + void decodePtr(T*& node, Decoder& decoder, Val*) + { + ValID id = decodeValID(decoder); + node = static_cast(getValByID(id)); + } - template - void decodePtr(T*& node, Decoder& decoder, Decl*) + template + void decodePtr(T*& node, Decoder& decoder, Decl*) + { + DeclID id = decodeDeclID(decoder); + node = static_cast(getDeclByID(id)); + } + + template + void decodePtr(T*& node, Decoder& decoder, DeclBase*) + { + if (decoder.getTag() == SerialBinary::kInt64FourCC) { DeclID id = decodeDeclID(decoder); node = static_cast(getDeclByID(id)); } - - template - void decodePtr(T*& node, Decoder& decoder, DeclBase*) - { - if(decoder.getTag() == SerialBinary::kInt64FourCC) - { - DeclID id = decodeDeclID(decoder); - node = static_cast(getDeclByID(id)); - } - else - { - decodeASTNode(node, decoder); - } - } - - template - void decodePtr(T*& node, Decoder& decoder, NodeBase*) + else { decodeASTNode(node, decoder); } + } + template + void decodePtr(T*& node, Decoder& decoder, NodeBase*) + { + decodeASTNode(node, decoder); + } - void decodeValue(UnhandledCase, Decoder& decoder); - void decodeValue(String& value, Decoder& decoder) - { - value = decoder.decodeString(); - } + void decodeValue(UnhandledCase, Decoder& decoder); - void decodeValue(Token& value, Decoder& decoder) - { - decode(value.type, decoder); - decode(value.flags, decoder); - decode(value.loc, decoder); - if (decoder.decodeNull()) - { - } - else - { - Name* name = nullptr; - decode(name, decoder); - value.setName(name); - } - } + void decodeValue(String& value, Decoder& decoder) { value = decoder.decodeString(); } - void decodeValue(NameLoc& value, Decoder& decoder) + void decodeValue(Token& value, Decoder& decoder) + { + decode(value.type, decoder); + decode(value.flags, decoder); + decode(value.loc, decoder); + if (decoder.decodeNull()) { - decode(value.name, decoder); } - - void decodeValue(SemanticVersion& value, Decoder& decoder) + else { - SemanticVersion::IntegerType rawValue = decoder.decode(); - value.setFromInteger(rawValue); - } - - void decodeValue(CapabilitySet& value, Decoder& decoder) - { - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - CapabilityTargetSet targetSet; - decode(targetSet, decoder); - value.getCapabilityTargetSets()[targetSet.target] = targetSet; - } + Name* name = nullptr; + decode(name, decoder); + value.setName(name); } + } - void decodeValue(CapabilityTargetSet& value, Decoder& decoder) - { - Decoder::WithKeyValuePair withPair(decoder); - decode(value.target, decoder); + void decodeValue(NameLoc& value, Decoder& decoder) { decode(value.name, decoder); } - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - CapabilityStageSet stageSet; - decode(stageSet, decoder); - value.shaderStageSets[stageSet.stage] = stageSet; - } - } + void decodeValue(SemanticVersion& value, Decoder& decoder) + { + SemanticVersion::IntegerType rawValue = decoder.decode(); + value.setFromInteger(rawValue); + } - void decodeValue(CapabilityStageSet& value, Decoder& decoder) + void decodeValue(CapabilitySet& value, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithKeyValuePair withPair(decoder); - decode(value.stage, decoder); - decode(value.atomSet, decoder); + CapabilityTargetSet targetSet; + decode(targetSet, decoder); + value.getCapabilityTargetSets()[targetSet.target] = targetSet; } + } + + void decodeValue(CapabilityTargetSet& value, Decoder& decoder) + { + Decoder::WithKeyValuePair withPair(decoder); + decode(value.target, decoder); - void decodeValue(CapabilityAtomSet& value, Decoder& decoder) + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - CapabilityAtom atom; - decode(atom, decoder); - value.add(UInt(atom)); - } + CapabilityStageSet stageSet; + decode(stageSet, decoder); + value.shaderStageSets[stageSet.stage] = stageSet; } + } - template - void decodeValue(std::optional& outValue, Decoder& decoder) + void decodeValue(CapabilityStageSet& value, Decoder& decoder) + { + Decoder::WithKeyValuePair withPair(decoder); + decode(value.stage, decoder); + decode(value.atomSet, decoder); + } + + void decodeValue(CapabilityAtomSet& value, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - if (decoder.decodeNull()) - { - outValue.reset(); - } - else - { - T value; - decode(value, decoder); - outValue = value; - } + CapabilityAtom atom; + decode(atom, decoder); + value.add(UInt(atom)); } + } - void decodeValue(SyntaxClass& syntaxClass, Decoder& decoder) + template + void decodeValue(std::optional& outValue, Decoder& decoder) + { + if (decoder.decodeNull()) { - ASTNodeType nodeType; - decode(nodeType, decoder); - syntaxClass = SyntaxClass(nodeType); + outValue.reset(); } - - template - void decodeValue(DeclRef& declRef, Decoder& decoder) + else { - decode(declRef.declRefBase, decoder); + T value; + decode(value, decoder); + outValue = value; } + } - void decodeValue(ValNodeOperand& value, Decoder& decoder) + void decodeValue(SyntaxClass& syntaxClass, Decoder& decoder) + { + ASTNodeType nodeType; + decode(nodeType, decoder); + syntaxClass = SyntaxClass(nodeType); + } + + template + void decodeValue(DeclRef& declRef, Decoder& decoder) + { + decode(declRef.declRefBase, decoder); + } + + void decodeValue(ValNodeOperand& value, Decoder& decoder) + { + Decoder::WithKeyValuePair withPair(decoder); + + decodeEnum(value.kind, decoder); + switch (value.kind) { - Decoder::WithKeyValuePair withPair(decoder); + case ValNodeOperandKind::ConstantValue: + decode(value.values.intOperand, decoder); + break; - decodeEnum(value.kind, decoder); - switch(value.kind) + case ValNodeOperandKind::ValNode: { - case ValNodeOperandKind::ConstantValue: - decode(value.values.intOperand, decoder); - break; - - case ValNodeOperandKind::ValNode: - { - Val* val = nullptr; - decode(val, decoder); - value.values.nodeOperand = val; - } - break; + Val* val = nullptr; + decode(val, decoder); + value.values.nodeOperand = val; + } + break; - case ValNodeOperandKind::ASTNode: - { - Decl* decl = nullptr; - decode(decl, decoder); - value.values.nodeOperand = decl; - } - break; + case ValNodeOperandKind::ASTNode: + { + Decl* decl = nullptr; + decode(decl, decoder); + value.values.nodeOperand = decl; } + break; } + } - void decodeValue(TypeExp& value, Decoder& decoder) - { - decode(value.type, decoder); - } + void decodeValue(TypeExp& value, Decoder& decoder) { decode(value.type, decoder); } - void decodeValue(QualType& value, Decoder& decoder) - { - Decoder::WithObject withObject(decoder); - decode(value.type, decoder); - decode(value.isLeftValue, decoder); - decode(value.hasReadOnlyOnTarget, decoder); - decode(value.isWriteOnly, decoder); - } + void decodeValue(QualType& value, Decoder& decoder) + { + Decoder::WithObject withObject(decoder); + decode(value.type, decoder); + decode(value.isLeftValue, decoder); + decode(value.hasReadOnlyOnTarget, decoder); + decode(value.isWriteOnly, decoder); + } - void decodeValue(MatrixCoord& value, Decoder& decoder) - { - Decoder::WithObject withObject(decoder); - decode(value.row, decoder); - decode(value.col, decoder); - } + void decodeValue(MatrixCoord& value, Decoder& decoder) + { + Decoder::WithObject withObject(decoder); + decode(value.row, decoder); + decode(value.col, decoder); + } - void decodeValue(SPIRVAsmOperand::Flavor& value, Decoder& decoder) - { - decodeEnum(value, decoder); - } + void decodeValue(SPIRVAsmOperand::Flavor& value, Decoder& decoder) + { + decodeEnum(value, decoder); + } - void decodeValue(SPIRVAsmOperand& value, Decoder& decoder) - { - Decoder::WithObject withObject(decoder); - decode(value.flavor, decoder); - decode(value.token, decoder); - decode(value.expr, decoder); - decode(value.bitwiseOrWith, decoder); - decode(value.knownValue, decoder); - decode(value.wrapInId, decoder); - decode(value.type, decoder); - } + void decodeValue(SPIRVAsmOperand& value, Decoder& decoder) + { + Decoder::WithObject withObject(decoder); + decode(value.flavor, decoder); + decode(value.token, decoder); + decode(value.expr, decoder); + decode(value.bitwiseOrWith, decoder); + decode(value.knownValue, decoder); + decode(value.wrapInId, decoder); + decode(value.type, decoder); + } - void decodeValue(SPIRVAsmInst& value, Decoder& decoder) - { - Decoder::WithObject withObject(decoder); - decode(value.opcode, decoder); - decode(value.operands, decoder); - } + void decodeValue(SPIRVAsmInst& value, Decoder& decoder) + { + Decoder::WithObject withObject(decoder); + decode(value.opcode, decoder); + decode(value.operands, decoder); + } - template - void decodeEnum(T& value, Decoder& decoder) - { - value = T(decoder.decode()); - } + template + void decodeEnum(T& value, Decoder& decoder) + { + value = T(decoder.decode()); + } - template - void decodeSimpleValue(T& value, Decoder& decoder) - { - value = decoder.decode(); - } + template + void decodeSimpleValue(T& value, Decoder& decoder) + { + value = decoder.decode(); + } - void decodeValue(bool& value, Decoder& decoder) { value = decoder.decodeBool(); } - void decodeValue(Int32& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(Int64& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(UInt32& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(UInt64& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(float& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(double& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(bool& value, Decoder& decoder) { value = decoder.decodeBool(); } + void decodeValue(Int32& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(Int64& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(UInt32& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(UInt64& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(float& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } + void decodeValue(double& value, Decoder& decoder) { decodeSimpleValue(value, decoder); } - void decodeValue(uint8_t& value, Decoder& decoder) - { - value = uint8_t(decoder.decode()); - } + void decodeValue(uint8_t& value, Decoder& decoder) + { + value = uint8_t(decoder.decode()); + } - void decodeValue(DeclVisibility& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(BaseType& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(BuiltinRequirementKind& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(ASTNodeType& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(ImageFormat& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(TypeTag& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(TryClauseType& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(CapabilityAtom& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(PreferRecomputeAttribute::SideEffectBehavior& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(LogicOperatorShortCircuitExpr::Flavor& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(TreatAsDifferentiableExpr::Flavor& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(DeclAssociationKind& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(TokenType& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(DeclVisibility& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(BaseType& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(BuiltinRequirementKind& value, Decoder& decoder) + { + decodeEnum(value, decoder); + } + void decodeValue(ASTNodeType& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(ImageFormat& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(TypeTag& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(TryClauseType& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(CapabilityAtom& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(PreferRecomputeAttribute::SideEffectBehavior& value, Decoder& decoder) + { + decodeEnum(value, decoder); + } + void decodeValue(LogicOperatorShortCircuitExpr::Flavor& value, Decoder& decoder) + { + decodeEnum(value, decoder); + } + void decodeValue(TreatAsDifferentiableExpr::Flavor& value, Decoder& decoder) + { + decodeEnum(value, decoder); + } + void decodeValue(DeclAssociationKind& value, Decoder& decoder) { decodeEnum(value, decoder); } + void decodeValue(TokenType& value, Decoder& decoder) { decodeEnum(value, decoder); } - void decodeValue(SourceLoc& value, Decoder& decoder) + void decodeValue(SourceLoc& value, Decoder& decoder) + { + if (!decoder.decodeNull()) { - if (!decoder.decodeNull()) - { - SerialSourceLocData::SourceLoc intermediate; - decoder.decode(intermediate); + SerialSourceLocData::SourceLoc intermediate; + decoder.decode(intermediate); - if (_sourceLocReader) - { - auto sourceLoc = _sourceLocReader->getSourceLoc(intermediate); - value = sourceLoc; - } + if (_sourceLocReader) + { + auto sourceLoc = _sourceLocReader->getSourceLoc(intermediate); + value = sourceLoc; } } + } - template - void decodeValue(T*& ptr, Decoder& decoder) - { - if (decoder.decodeNull()) - ptr = nullptr; - else - decodePtr(ptr, decoder, (T*)nullptr); - } + template + void decodeValue(T*& ptr, Decoder& decoder) + { + if (decoder.decodeNull()) + ptr = nullptr; + else + decodePtr(ptr, decoder, (T*)nullptr); + } - template - void decodeValue(RefPtr& ptr, Decoder& decoder) + template + void decodeValue(RefPtr& ptr, Decoder& decoder) + { + if (decoder.decodeNull()) + ptr = nullptr; + else { - if (decoder.decodeNull()) - ptr = nullptr; - else - { - // Hi Future Tess, - // - // The next step here is decoding logic for `WitnessTable`s. - // + // Hi Future Tess, + // + // The next step here is decoding logic for `WitnessTable`s. + // - decodePtr(*ptr.writeRef(), decoder, (T*)nullptr); - } + decodePtr(*ptr.writeRef(), decoder, (T*)nullptr); } + } - void decodeValue(Modifiers& modifiers, Decoder& decoder) - { - Modifier** link = &modifiers.first; + void decodeValue(Modifiers& modifiers, Decoder& decoder) + { + Modifier** link = &modifiers.first; - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - Modifier* modifier = nullptr; - decode(modifier, decoder); + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) + { + Modifier* modifier = nullptr; + decode(modifier, decoder); - *link = modifier; - link = &modifier->next; - } + *link = modifier; + link = &modifier->next; } + } - template - void decodeValue(ShortList& array, Decoder& decoder) + template + void decodeValue(ShortList& array, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - T element; - decode(element, decoder); - array.add(element); - } + T element; + decode(element, decoder); + array.add(element); } + } - template - void decode(List& array, Decoder& decoder) + template + void decode(List& array, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithArray withArray(decoder); - while(decoder.hasElements()) - { - T element; - decode(element, decoder); - array.add(element); - } + T element; + decode(element, decoder); + array.add(element); } + } - template - void decode(T (&array)[N], Decoder& decoder) + template + void decode(T (&array)[N], Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + for (auto& element : array) { - Decoder::WithArray withArray(decoder); - for (auto& element : array) - { - decode(element, decoder); - } + decode(element, decoder); } + } - template - void decode(OrderedDictionary & dictionary, Decoder& decoder) + template + void decode(OrderedDictionary& dictionary, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - Decoder::WithKeyValuePair withPair(decoder); + Decoder::WithKeyValuePair withPair(decoder); - K key; V value; - decode(key, decoder); - decode(value, decoder); + K key; + V value; + decode(key, decoder); + decode(value, decoder); - dictionary.add(key, value); - } + dictionary.add(key, value); } + } - template - void decode(Dictionary& dictionary, Decoder& decoder) + template + void decode(Dictionary& dictionary, Decoder& decoder) + { + Decoder::WithArray withArray(decoder); + while (decoder.hasElements()) { - Decoder::WithArray withArray(decoder); - while (decoder.hasElements()) - { - Decoder::WithKeyValuePair withPair(decoder); + Decoder::WithKeyValuePair withPair(decoder); - K key; V value; - decode(key, decoder); - decode(value, decoder); + K key; + V value; + decode(key, decoder); + decode(value, decoder); - dictionary.add(key, value); - } + dictionary.add(key, value); } + } - template - void decode(T& outValue, Decoder& decoder) - { - decodeValue(outValue, decoder); - } + template + void decode(T& outValue, Decoder& decoder) + { + decodeValue(outValue, decoder); + } #if 0 // FIDDLE TEMPLATE: %for _,T in ipairs(Slang.NodeBase.subclasses) do @@ -1554,21 +1518,21 @@ namespace Slang #define FIDDLE_GENERATED_OUTPUT_ID 1 #include "slang-serialize-ast.cpp.fiddle" #endif // FIDDLE END - - }; - - ModuleDecl* readSerializedModuleAST( - Linkage* linkage, - ASTBuilder* astBuilder, - DiagnosticSink* sink, - RiffContainer::Chunk* chunk, - SerialSourceLocReader* sourceLocReader, - SourceLoc requestingSourceLoc) - { - ASTDecodingContext context(linkage, astBuilder, sink, chunk, sourceLocReader, requestingSourceLoc); - context.decodeAll(); - auto node = context.getDeclByID(0); - auto moduleDecl = as(node); - return moduleDecl; - } +}; + +ModuleDecl* readSerializedModuleAST( + Linkage* linkage, + ASTBuilder* astBuilder, + DiagnosticSink* sink, + RiffContainer::Chunk* chunk, + SerialSourceLocReader* sourceLocReader, + SourceLoc requestingSourceLoc) +{ + ASTDecodingContext + context(linkage, astBuilder, sink, chunk, sourceLocReader, requestingSourceLoc); + context.decodeAll(); + auto node = context.getDeclByID(0); + auto moduleDecl = as(node); + return moduleDecl; } +} // namespace Slang diff --git a/source/slang/slang-serialize-ast.h b/source/slang/slang-serialize-ast.h index ef278f15ead..6adeae8dd8b 100644 --- a/source/slang/slang-serialize-ast.h +++ b/source/slang/slang-serialize-ast.h @@ -6,23 +6,23 @@ #include "slang-ast-all.h" #include "slang-ast-builder.h" #include "slang-ast-support-types.h" -#include "slang-serialize.h" #include "slang-serialize-source-loc.h" +#include "slang-serialize.h" namespace Slang { - void writeSerializedModuleAST( - Encoder* encoder, - ModuleDecl* moduleDecl, - SerialSourceLocWriter* sourceLocWriter); +void writeSerializedModuleAST( + Encoder* encoder, + ModuleDecl* moduleDecl, + SerialSourceLocWriter* sourceLocWriter); - ModuleDecl* readSerializedModuleAST( - Linkage* linkage, - ASTBuilder* astBuilder, - DiagnosticSink* sink, - RiffContainer::Chunk* chunk, - SerialSourceLocReader* sourceLocReader, - SourceLoc requestingSourceLoc); +ModuleDecl* readSerializedModuleAST( + Linkage* linkage, + ASTBuilder* astBuilder, + DiagnosticSink* sink, + RiffContainer::Chunk* chunk, + SerialSourceLocReader* sourceLocReader, + SourceLoc requestingSourceLoc); } // namespace Slang diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp index 5038dcfec34..25c4b97b4b0 100644 --- a/source/slang/slang-serialize-container.cpp +++ b/source/slang/slang-serialize-container.cpp @@ -15,397 +15,375 @@ namespace Slang { - struct ModuleEncodingContext +struct ModuleEncodingContext +{ +public: + ModuleEncodingContext(SerialContainerUtil::WriteOptions const& options, Stream* stream) + : options(options), encoder(stream), containerStringPool(StringSlicePool::Style::Default) { - public: - ModuleEncodingContext( - SerialContainerUtil::WriteOptions const& options, - Stream* stream) - : options(options) - , encoder(stream) - , containerStringPool(StringSlicePool::Style::Default) + if (options.optionFlags & SerialOptionFlag::SourceLocation) { - if (options.optionFlags & SerialOptionFlag::SourceLocation) - { - sourceLocWriter = new SerialSourceLocWriter(options.sourceManager); - } + sourceLocWriter = new SerialSourceLocWriter(options.sourceManager); } + } + + ~ModuleEncodingContext() + { + encoder.setRIFFChunk(encoder.getRIFF()->getRoot()); + encodeFinalPieces(); + } - ~ModuleEncodingContext() + SlangResult encodeModuleList(FrontEndCompileRequest* frontEndReq) + { + // Encoding a front-end compile request into a RIFF + // is simply a matter of encoding the module for each + // of the translation units that got compiled. + // + Encoder::WithKeyValuePair withArray(&encoder, SerialBinary::kModuleListFourCc); + for (TranslationUnitRequest* translationUnit : frontEndReq->translationUnits) { - encoder.setRIFFChunk(encoder.getRIFF()->getRoot()); - encodeFinalPieces(); + SLANG_RETURN_ON_FAIL(encode(translationUnit->module)); } + return SLANG_OK; + } + + SlangResult encode(FrontEndCompileRequest* frontEndReq) + { + Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); + SLANG_RETURN_ON_FAIL(encodeModuleList(frontEndReq)); + return SLANG_OK; + } - SlangResult encodeModuleList( - FrontEndCompileRequest* frontEndReq) + SlangResult encode(EndToEndCompileRequest* request) + { + Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); + + // Encoding an end-to-end compile request starts with the same + // work as for a front-end request: we encode each of + // the modules for the translation units. + // + SLANG_RETURN_ON_FAIL(encodeModuleList(request->getFrontEndReq())); + // + // If code generation is disabled, then we can skip all further + // steps, and the encoding process is no different + // than for a front-end request. + // + if (request->getOptionSet().getBoolOption(CompilerOptionName::SkipCodeGen)) { - // Encoding a front-end compile request into a RIFF - // is simply a matter of encoding the module for each - // of the translation units that got compiled. - // - Encoder::WithKeyValuePair withArray(&encoder, SerialBinary::kModuleListFourCc); - for (TranslationUnitRequest* translationUnit : frontEndReq->translationUnits) - { - SLANG_RETURN_ON_FAIL(encode(translationUnit->module)); - } return SLANG_OK; } - SlangResult encode( - FrontEndCompileRequest* frontEndReq) + // If code generation is enabled, then we need to encode + // information on each of the code generation targets, as well + // as the entry points. + // + // We start with the targets, each of which will have a Slang IR + // representation of the layout information for the program + // on that target. + // + auto linkage = request->getLinkage(); + auto sink = request->getSink(); + auto program = request->getSpecializedGlobalAndEntryPointsComponentType(); { - Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); - SLANG_RETURN_ON_FAIL(encodeModuleList(frontEndReq)); - return SLANG_OK; + Encoder::WithArray withArray(&encoder); // kContainerFourCc + + for (auto target : linkage->targets) + { + auto targetProgram = program->getTargetProgram(target); + encode(targetProgram, sink); + } } - SlangResult encode( - EndToEndCompileRequest* request) + // The compiled `program` may also have zero or more entry points, + // and we need to encode information about each of them. + // { - Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); + Encoder::WithArray withArray(&encoder, SerialBinary::kEntryPointListFourCc); - // Encoding an end-to-end compile request starts with the same - // work as for a front-end request: we encode each of - // the modules for the translation units. - // - SLANG_RETURN_ON_FAIL(encodeModuleList(request->getFrontEndReq())); - // - // If code generation is disabled, then we can skip all further - // steps, and the encoding process is no different - // than for a front-end request. - // - if (request->getOptionSet().getBoolOption(CompilerOptionName::SkipCodeGen)) + auto entryPointCount = program->getEntryPointCount(); + for (Index ii = 0; ii < entryPointCount; ++ii) { - return SLANG_OK; + auto entryPoint = program->getEntryPoint(ii); + auto entryPointMangledName = program->getEntryPointMangledName(ii); + encode(entryPoint, entryPointMangledName); } + } - // If code generation is enabled, then we need to encode - // information on each of the code generation targets, as well - // as the entry points. - // - // We start with the targets, each of which will have a Slang IR - // representation of the layout information for the program - // on that target. - // - auto linkage = request->getLinkage(); - auto sink = request->getSink(); - auto program = request->getSpecializedGlobalAndEntryPointsComponentType(); - { - Encoder::WithArray withArray(&encoder); // kContainerFourCc + return SLANG_OK; + } - for (auto target : linkage->targets) - { - auto targetProgram = program->getTargetProgram(target); - encode(targetProgram, sink); - } - } + SlangResult encode(TargetProgram* targetProgram, DiagnosticSink* sink) + { + // TODO: + // Serialization of target component IR is causing the embedded precompiled binary + // feature to fail. The resulting data modules contain both TU IR and TC IR, with only + // one module header. Yong suggested to ignore the TC IR for now, though also that + // OV was using the feature, so disabling this might cause problems. - // The compiled `program` may also have zero or more entry points, - // and we need to encode information about each of them. - // - { - Encoder::WithArray withArray(&encoder, SerialBinary::kEntryPointListFourCc); + IRModule* irModule = targetProgram->getOrCreateIRModuleForLayout(sink); - auto entryPointCount = program->getEntryPointCount(); - for (Index ii = 0; ii < entryPointCount; ++ii) - { - auto entryPoint = program->getEntryPoint(ii); - auto entryPointMangledName = program->getEntryPointMangledName(ii); - encode(entryPoint, entryPointMangledName); - } - } + // Okay, we need to serialize this target program and its IR too... + IRSerialData serialData; + IRSerialWriter writer; - return SLANG_OK; - } + SLANG_RETURN_ON_FAIL( + writer.write(irModule, sourceLocWriter, options.optionFlags, &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); - SlangResult encode(TargetProgram* targetProgram, DiagnosticSink* sink) - { - // TODO: - // Serialization of target component IR is causing the embedded precompiled binary - // feature to fail. The resulting data modules contain both TU IR and TC IR, with only - // one module header. Yong suggested to ignore the TC IR for now, though also that - // OV was using the feature, so disabling this might cause problems. + return SLANG_OK; + } - IRModule* irModule = targetProgram->getOrCreateIRModuleForLayout(sink); + void encode(Name* name) { encoder.encode(name->text); } - // Okay, we need to serialize this target program and its IR too... - IRSerialData serialData; - IRSerialWriter writer; + void encode(String const& value) { encoder.encode(value); } - SLANG_RETURN_ON_FAIL(writer.write(irModule, sourceLocWriter, options.optionFlags, &serialData)); - SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); + void encode(uint32_t value) { encoder.encode(UInt(value)); } - return SLANG_OK; - } + void encodeData(void const* data, size_t size) { encoder.encodeData(data, size); } - void encode(Name* name) - { - encoder.encode(name->text); - } + SlangResult encode(EntryPoint* entryPoint, String const& entryPointMangledName) + { + Encoder::WithObject withObject(&encoder, SerialBinary::kEntryPointFourCc); - void encode(String const& value) { - encoder.encode(value); + Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); + encode(entryPoint->getName()); } - - void encode(uint32_t value) { - encoder.encode(UInt(value)); + Encoder::WithObject withProperty(&encoder, SerialBinary::kProfileFourCC); + encode(entryPoint->getProfile().raw); } - - void encodeData(void const* data, size_t size) { - encoder.encodeData(data, size); + Encoder::WithObject withProperty(&encoder, SerialBinary::kMangledNameFourCC); + encode(entryPointMangledName); } - SlangResult encode(EntryPoint* entryPoint, String const& entryPointMangledName) - { - Encoder::WithObject withObject(&encoder, SerialBinary::kEntryPointFourCc); + return SLANG_OK; + } - { - Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); - encode(entryPoint->getName()); - } - { - Encoder::WithObject withProperty(&encoder, SerialBinary::kProfileFourCC); - encode(entryPoint->getProfile().raw); - } - { - Encoder::WithObject withProperty(&encoder, SerialBinary::kMangledNameFourCC); - encode(entryPointMangledName); - } + SlangResult encode(Module* module) + { + if (!(options.optionFlags & (SerialOptionFlag::IRModule | SerialOptionFlag::ASTModule))) return SLANG_OK; - } + Encoder::WithObject withModule(&encoder, SerialBinary::kModuleFourCC); - SlangResult encode(Module* module) + // The first piece that we write for a module is its header. + // The header is intended to provide information that can be + // used to determine if a precompiled module is up-to-date. + // + // Update(tfoley): Okay, let's skip the whole header idea and just + // serialize these things as properties of the module itself... { - if (!(options.optionFlags & (SerialOptionFlag::IRModule | SerialOptionFlag::ASTModule))) - return SLANG_OK; - - Encoder::WithObject withModule(&encoder, SerialBinary::kModuleFourCC); - - // The first piece that we write for a module is its header. - // The header is intended to provide information that can be - // used to determine if a precompiled module is up-to-date. + // So many things need the module name, that it makes + // sense to serialize it separately from all the rest. // - // Update(tfoley): Okay, let's skip the whole header idea and just - // serialize these things as properties of the module itself... { - // So many things need the module name, that it makes - // sense to serialize it separately from all the rest. - // - { - Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); - encoder.encodeString(module->getNameObj()->text); - } - - // The header includes a digest of all the compile options and - // the files that the compiled result depended on. - // - auto digest = module->computeDigest(); - encoder.encodeData(PropertyKeys::Digest, digest.data, sizeof(digest.data)); - - // The header includes an array of the paths of all of the - // files that the compiled result depended on. - // - encodeModuleDependencyPaths(module); + Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); + encoder.encodeString(module->getNameObj()->text); } - // If serialization of Slang IR modules is enabled, and there - // is IR available for this module, then we we encode it. + // The header includes a digest of all the compile options and + // the files that the compiled result depended on. // - if ((options.optionFlags & SerialOptionFlag::IRModule)) - { - if (auto irModule = module->getIRModule()) - { - Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys::IRModule); - - IRSerialData serialData; - IRSerialWriter writer; - SLANG_RETURN_ON_FAIL(writer.write( - irModule, - sourceLocWriter, - options.optionFlags, - &serialData)); - SLANG_RETURN_ON_FAIL( - IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); - } - } + auto digest = module->computeDigest(); + encoder.encodeData(PropertyKeys::Digest, digest.data, sizeof(digest.data)); - // If serialization of AST information is enabled, and we have AST - // information available, then we serialize it here. + // The header includes an array of the paths of all of the + // files that the compiled result depended on. // - if (options.optionFlags & SerialOptionFlag::ASTModule) + encodeModuleDependencyPaths(module); + } + + // If serialization of Slang IR modules is enabled, and there + // is IR available for this module, then we we encode it. + // + if ((options.optionFlags & SerialOptionFlag::IRModule)) + { + if (auto irModule = module->getIRModule()) { - if (auto moduleDecl = module->getModuleDecl()) - { - Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys::ASTModule); + Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys::IRModule); - writeSerializedModuleAST(&encoder, moduleDecl, sourceLocWriter); - } + IRSerialData serialData; + IRSerialWriter writer; + SLANG_RETURN_ON_FAIL( + writer.write(irModule, sourceLocWriter, options.optionFlags, &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); } - - return SLANG_OK; } - SlangResult encodeModuleDependencyPaths(Module* module) + // If serialization of AST information is enabled, and we have AST + // information available, then we serialize it here. + // + if (options.optionFlags & SerialOptionFlag::ASTModule) { - Encoder::WithObject withProperty(&encoder, PropertyKeys::FileDependencies); - - // TODO(tfoley): This is some of the most complicated logic - // in the encoding system, because it tries to translate - // the file dependency paths into something that isn't - // specific to the machine on which a module was built. - // - // The comments that follow are from the original implementation - // of this logic, because I cannot state with confidence - // that I know what's happening in all of this. + if (auto moduleDecl = module->getModuleDecl()) + { + Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys::ASTModule); + writeSerializedModuleAST(&encoder, moduleDecl, sourceLocWriter); + } + } - // Here we assume that the first file in the file dependencies is the module's file path. - // We store the module's file path as a relative path with respect to the first search - // directory that contains the module, and store the paths of dependent files as relative - // paths with respect to the module's path. + return SLANG_OK; + } - // First, we try to extract the module's main file path from the file dependency list. - auto fileDependencies = module->getFileDependencies(); - String canonicalModulePath, moduleDir; - if (fileDependencies.getCount() != 0) - { - IncludeSystem includeSystem( - &module->getLinkage()->getSearchDirectories(), - module->getLinkage()->getFileSystemExt(), - module->getLinkage()->getSourceManager()); - PathInfo outFoundSourcePath; - // If we can find the first file, use that as the module's path. - if (SLANG_SUCCEEDED(includeSystem.findFile( + SlangResult encodeModuleDependencyPaths(Module* module) + { + Encoder::WithObject withProperty(&encoder, PropertyKeys::FileDependencies); + + // TODO(tfoley): This is some of the most complicated logic + // in the encoding system, because it tries to translate + // the file dependency paths into something that isn't + // specific to the machine on which a module was built. + // + // The comments that follow are from the original implementation + // of this logic, because I cannot state with confidence + // that I know what's happening in all of this. + + + // Here we assume that the first file in the file dependencies is the module's file path. + // We store the module's file path as a relative path with respect to the first search + // directory that contains the module, and store the paths of dependent files as relative + // paths with respect to the module's path. + + // First, we try to extract the module's main file path from the file dependency list. + auto fileDependencies = module->getFileDependencies(); + String canonicalModulePath, moduleDir; + if (fileDependencies.getCount() != 0) + { + IncludeSystem includeSystem( + &module->getLinkage()->getSearchDirectories(), + module->getLinkage()->getFileSystemExt(), + module->getLinkage()->getSourceManager()); + PathInfo outFoundSourcePath; + // If we can find the first file, use that as the module's path. + if (SLANG_SUCCEEDED(includeSystem.findFile( fileDependencies[0]->getPathInfo().foundPath, "", outFoundSourcePath))) - { - canonicalModulePath = outFoundSourcePath.foundPath; - Path::getCanonical(canonicalModulePath, canonicalModulePath); - moduleDir = Path::getParentDirectory(canonicalModulePath); - } + { + canonicalModulePath = outFoundSourcePath.foundPath; + Path::getCanonical(canonicalModulePath, canonicalModulePath); + moduleDir = Path::getParentDirectory(canonicalModulePath); } + } - // If we can't find the module's path from the file dependencies list above, - // use the file path stored on the module as a fallback. - // Note that if the module is loaded from a binary precompiled module, - // this path will be pointing to that binary file instead of the original source file. - if (!canonicalModulePath.getLength()) + // If we can't find the module's path from the file dependencies list above, + // use the file path stored on the module as a fallback. + // Note that if the module is loaded from a binary precompiled module, + // this path will be pointing to that binary file instead of the original source file. + if (!canonicalModulePath.getLength()) + { + if (auto modulePath = module->getFilePath()) { - if (auto modulePath = module->getFilePath()) - { - canonicalModulePath = modulePath; - Path::getCanonical(canonicalModulePath, canonicalModulePath); - moduleDir = Path::getParentDirectory(canonicalModulePath); - } + canonicalModulePath = modulePath; + Path::getCanonical(canonicalModulePath, canonicalModulePath); + moduleDir = Path::getParentDirectory(canonicalModulePath); } + } - // Find the first search directory that contains the module's main file path, - // so we can store the module's path (the first entry in the dependent files list) - // as a relative path with respect to that directory. + // Find the first search directory that contains the module's main file path, + // so we can store the module's path (the first entry in the dependent files list) + // as a relative path with respect to that directory. - String linkageRoot = "."; - if (auto linkage = module->getLinkage()) + String linkageRoot = "."; + if (auto linkage = module->getLinkage()) + { + for (const auto& searchDir : linkage->getSearchDirectories().searchDirectories) { - for (const auto& searchDir : linkage->getSearchDirectories().searchDirectories) + String fullSearchDir; + Path::getCanonical(searchDir.path, fullSearchDir); + String relativePath = Path::getRelativePath(fullSearchDir, canonicalModulePath); + if (!Path::hasRelativeElement(relativePath)) { - String fullSearchDir; - Path::getCanonical(searchDir.path, fullSearchDir); - String relativePath = Path::getRelativePath(fullSearchDir, canonicalModulePath); - if (!Path::hasRelativeElement(relativePath)) - { - linkageRoot = searchDir.path; - break; - } + linkageRoot = searchDir.path; + break; } } - Path::getCanonical(linkageRoot, linkageRoot); + } + Path::getCanonical(linkageRoot, linkageRoot); - Encoder::WithArray withArray(&encoder); - for (auto file : fileDependencies) + Encoder::WithArray withArray(&encoder); + for (auto file : fileDependencies) + { + if (file->getPathInfo().hasFoundPath()) { - if (file->getPathInfo().hasFoundPath()) - { - String canonicalFilePath = file->getPathInfo().foundPath; - Path::getCanonical(file->getPathInfo().foundPath, canonicalFilePath); + String canonicalFilePath = file->getPathInfo().foundPath; + Path::getCanonical(file->getPathInfo().foundPath, canonicalFilePath); - // If the dependnet file is the same as the module's file path, store it as a - // relative path with respect to the search directory discovered above. - if (file->getPathInfo().hasFileFoundPath()) + // If the dependnet file is the same as the module's file path, store it as a + // relative path with respect to the search directory discovered above. + if (file->getPathInfo().hasFileFoundPath()) + { + if (canonicalFilePath == canonicalModulePath) { - if (canonicalFilePath == canonicalModulePath) - { - auto relativeModulePath = - Path::getRelativePath(linkageRoot, canonicalModulePath); - - encoder.encodeString(relativeModulePath); - } - else - { - // For all other dependnet files, store them as relative paths with respect - // to the module's path. - canonicalFilePath = Path::getRelativePath(moduleDir, canonicalFilePath); - encoder.encodeString(canonicalFilePath); - } + auto relativeModulePath = + Path::getRelativePath(linkageRoot, canonicalModulePath); + + encoder.encodeString(relativeModulePath); } else { - // If the module is coming from string instead of an actual file, store it as - // is. - encoder.encodeString(canonicalModulePath); + // For all other dependnet files, store them as relative paths with respect + // to the module's path. + canonicalFilePath = Path::getRelativePath(moduleDir, canonicalFilePath); + encoder.encodeString(canonicalFilePath); } } else { - encoder.encodeString(file->getPathInfo().getMostUniqueIdentity()); + // If the module is coming from string instead of an actual file, store it as + // is. + encoder.encodeString(canonicalModulePath); } } - - return SLANG_OK; + else + { + encoder.encodeString(file->getPathInfo().getMostUniqueIdentity()); + } } - SlangResult encodeFinalPieces() - { - // We can now output the debug information. This is for all IR and AST - if (sourceLocWriter) - { - // Write out the debug info - SerialSourceLocData debugData; - sourceLocWriter->write(&debugData); + return SLANG_OK; + } - debugData.writeContainer(encoder.getRIFF()); - } + SlangResult encodeFinalPieces() + { + // We can now output the debug information. This is for all IR and AST + if (sourceLocWriter) + { + // Write out the debug info + SerialSourceLocData debugData; + sourceLocWriter->write(&debugData); - // Write the container string table - if (containerStringPool.getAdded().getCount() > 0) - { - Encoder::WithKeyValuePair withKey(&encoder, SerialBinary::kStringTableFourCc); + debugData.writeContainer(encoder.getRIFF()); + } - List encodedTable; - SerialStringTableUtil::encodeStringTable(containerStringPool, encodedTable); + // Write the container string table + if (containerStringPool.getAdded().getCount() > 0) + { + Encoder::WithKeyValuePair withKey(&encoder, SerialBinary::kStringTableFourCc); - encoder.encodeData(encodedTable.getBuffer(), encodedTable.getCount()); - } + List encodedTable; + SerialStringTableUtil::encodeStringTable(containerStringPool, encodedTable); - return SLANG_OK; + encoder.encodeData(encodedTable.getBuffer(), encodedTable.getCount()); } + return SLANG_OK; + } - private: - SerialContainerUtil::WriteOptions const& options; - RefPtr sourceLocWriter; - // The string pool used across the whole of the container - StringSlicePool containerStringPool; +private: + SerialContainerUtil::WriteOptions const& options; + RefPtr sourceLocWriter; + + // The string pool used across the whole of the container + StringSlicePool containerStringPool; - Encoder encoder; - }; + Encoder encoder; +}; // // To serialize a module (or compile request) to a stream, we first @@ -463,7 +441,8 @@ ModuleChunkRef ModuleChunkRef::find(RiffContainer* container) SHA1::Digest ModuleChunkRef::getDigest() { - auto foundChunk = static_cast(ptr()->findContained(PropertyKeys::Digest)); + auto foundChunk = + static_cast(ptr()->findContained(PropertyKeys::Digest)); if (!foundChunk) { SLANG_UNEXPECTED("module chunk had no digest"); @@ -494,15 +473,19 @@ String ModuleChunkRef::getName() IRModuleChunkRef ModuleChunkRef::findIR() { auto foundProperty = ptr()->findContainedList(PropertyKeys::IRModule); - if (!foundProperty) return IRModuleChunkRef(nullptr); - return IRModuleChunkRef(static_cast(foundProperty->getFirstContainedChunk())); + if (!foundProperty) + return IRModuleChunkRef(nullptr); + return IRModuleChunkRef( + static_cast(foundProperty->getFirstContainedChunk())); } ASTModuleChunkRef ModuleChunkRef::findAST() { auto foundProperty = ptr()->findContainedList(PropertyKeys::ASTModule); - if (!foundProperty) return ASTModuleChunkRef(nullptr); - return ASTModuleChunkRef(static_cast(foundProperty->getFirstContainedChunk())); + if (!foundProperty) + return ASTModuleChunkRef(nullptr); + return ASTModuleChunkRef( + static_cast(foundProperty->getFirstContainedChunk())); } ContainerChunkRef ContainerChunkRef::find(RiffContainer* container) @@ -617,7 +600,7 @@ SlangResult readSourceLocationsFromDebugChunk( // location information to other deserialization tasks (both IR // and AST deserialization). // - auto reader = RefPtr( new SerialSourceLocReader() ); + auto reader = RefPtr(new SerialSourceLocReader()); SLANG_RETURN_ON_FAIL(reader->read(&intermediateData, sourceManager)); outReader = reader; @@ -646,17 +629,14 @@ SlangResult decodeModuleIR( if (!listChunk) return SLANG_FAIL; IRSerialData serialData; - SLANG_RETURN_ON_FAIL(IRSerialReader::readContainer( - listChunk, - &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialReader::readContainer(listChunk, &serialData)); // Next we read the actual IR representation out from the // `serialData`. This is the step that may pull source-location // information from the provided `sourceLocReader`. // IRSerialReader reader; - SLANG_RETURN_ON_FAIL( - reader.read(serialData, session, sourceLocReader, outIRModule)); + SLANG_RETURN_ON_FAIL(reader.read(serialData, session, sourceLocReader, outIRModule)); return SLANG_OK; } diff --git a/source/slang/slang-serialize-container.h b/source/slang/slang-serialize-container.h index 9545d545ffd..4c1053a6d16 100644 --- a/source/slang/slang-serialize-container.h +++ b/source/slang/slang-serialize-container.h @@ -53,10 +53,7 @@ struct SerialContainerUtil EndToEndCompileRequest* request, const WriteOptions& options, Stream* stream); - static SlangResult write( - Module* module, - const WriteOptions& options, - Stream* stream); + static SlangResult write(Module* module, const WriteOptions& options, Stream* stream); }; @@ -65,7 +62,8 @@ struct ChunkRef public: ChunkRef(RiffContainer::Chunk* chunk) : _chunk(chunk) - {} + { + } RiffContainer::Chunk* ptr() const { return _chunk; } @@ -78,11 +76,12 @@ struct DataChunkRef : ChunkRef public: DataChunkRef(RiffContainer::DataChunk* chunk) : ChunkRef(chunk) - {} + { + } RiffContainer::DataChunk* ptr() const { return static_cast(_chunk); } - operator RiffContainer::DataChunk* () const { return ptr(); } + operator RiffContainer::DataChunk*() const { return ptr(); } }; @@ -95,17 +94,12 @@ struct ChunkRefList public: Iterator(RiffContainer::Chunk* chunk) : _chunk(chunk) - {} - - bool operator!=(Iterator const& other) const { - return _chunk != other._chunk; } - void operator++() - { - _chunk = _chunk->m_next; - } + bool operator!=(Iterator const& other) const { return _chunk != other._chunk; } + + void operator++() { _chunk = _chunk->m_next; } T operator*() { @@ -128,19 +122,16 @@ struct ChunkRefList return count; } - T getFirst() - { - return *begin(); - } + T getFirst() { return *begin(); } - ChunkRefList() - {} + ChunkRefList() {} ChunkRefList(RiffContainer::ListChunk* list) : _list(list) - {} + { + } - operator RiffContainer::ListChunk* () const { return _list; } + operator RiffContainer::ListChunk*() const { return _list; } private: RiffContainer::ListChunk* _list = nullptr; @@ -151,15 +142,15 @@ struct ListChunkRef : ChunkRef public: ListChunkRef(RiffContainer::Chunk* chunk) : ChunkRef(chunk) - {} + { + } RiffContainer::ListChunk* ptr() const { return static_cast(_chunk); } - operator RiffContainer::ListChunk* () const { return ptr(); } + operator RiffContainer::ListChunk*() const { return ptr(); } }; - struct StringChunkRef : DataChunkRef { public: @@ -171,7 +162,8 @@ struct IRModuleChunkRef : ListChunkRef public: explicit IRModuleChunkRef(RiffContainer::ListChunk* chunk) : ListChunkRef(chunk) - {} + { + } }; struct ASTModuleChunkRef : ListChunkRef @@ -179,7 +171,8 @@ struct ASTModuleChunkRef : ListChunkRef public: explicit ASTModuleChunkRef(RiffContainer::ListChunk* chunk) : ListChunkRef(chunk) - {} + { + } }; struct ModuleChunkRef : ListChunkRef @@ -199,7 +192,8 @@ struct ModuleChunkRef : ListChunkRef protected: ModuleChunkRef(RiffContainer::Chunk* chunk) : ListChunkRef(chunk) - {} + { + } }; struct EntryPointChunkRef : ListChunkRef @@ -212,7 +206,8 @@ struct EntryPointChunkRef : ListChunkRef protected: EntryPointChunkRef(RiffContainer::Chunk* chunk) : ListChunkRef(chunk) - {} + { + } }; struct ContainerChunkRef : ListChunkRef @@ -227,14 +222,14 @@ struct ContainerChunkRef : ListChunkRef protected: ContainerChunkRef(RiffContainer::Chunk* chunk) : ListChunkRef(chunk) - {} + { + } }; /// Attempt to find a debug-info chunk relative to /// the given `startingChunk`. /// -RiffContainer::ListChunk* findDebugChunk( - RiffContainer::Chunk* startingChunk); +RiffContainer::ListChunk* findDebugChunk(RiffContainer::Chunk* startingChunk); SlangResult readSourceLocationsFromDebugChunk( RiffContainer::ListChunk* debugChunk, diff --git a/source/slang/slang-serialize-types.h b/source/slang/slang-serialize-types.h index 9ca12ac8b3c..cd2b4c99c6f 100644 --- a/source/slang/slang-serialize-types.h +++ b/source/slang/slang-serialize-types.h @@ -116,7 +116,9 @@ struct SerialListUtil }; template -struct PropertyKeys {}; +struct PropertyKeys +{ +}; template<> struct PropertyKeys diff --git a/source/slang/slang-serialize.h b/source/slang/slang-serialize.h index 7f4d823685a..54c1af74289 100644 --- a/source/slang/slang-serialize.h +++ b/source/slang/slang-serialize.h @@ -30,27 +30,19 @@ struct ValNodeDesc; struct Encoder { public: - Encoder( - Stream* stream) + Encoder(Stream* stream) : _stream(stream) - {} - - ~Encoder() { - RiffUtil::write(&_riff, _stream); } + ~Encoder() { RiffUtil::write(&_riff, _stream); } + void beginArray(FourCC typeCode) { - _riff.startChunk( - RiffContainer::Chunk::Kind::List, - typeCode); + _riff.startChunk(RiffContainer::Chunk::Kind::List, typeCode); } - void beginArray() - { - beginArray(SerialBinary::kArrayFourCC); - } + void beginArray() { beginArray(SerialBinary::kArrayFourCC); } void endArray() { @@ -60,45 +52,28 @@ struct Encoder void beginObject(FourCC typeCode) { - _riff.startChunk( - RiffContainer::Chunk::Kind::List, - typeCode); + _riff.startChunk(RiffContainer::Chunk::Kind::List, typeCode); } - void beginObject() - { - beginObject(SerialBinary::kObjectFourCC); - } + void beginObject() { beginObject(SerialBinary::kObjectFourCC); } - void endObject() - { - _riff.endChunk(); - } + void endObject() { _riff.endChunk(); } void beginKeyValuePair() { - _riff.startChunk( - RiffContainer::Chunk::Kind::List, - SerialBinary::kPairFourCC); + _riff.startChunk(RiffContainer::Chunk::Kind::List, SerialBinary::kPairFourCC); } - void endKeyValuePair() - { - _riff.endChunk(); - } + void endKeyValuePair() { _riff.endChunk(); } void beginKeyValuePair(FourCC keyCode) { - _riff.startChunk( - RiffContainer::Chunk::Kind::List, - keyCode); + _riff.startChunk(RiffContainer::Chunk::Kind::List, keyCode); } void encodeData(FourCC typeCode, void const* data, size_t size) { - _riff.startChunk( - RiffContainer::Chunk::Kind::Data, - typeCode); + _riff.startChunk(RiffContainer::Chunk::Kind::Data, typeCode); _riff.write(data, size); _riff.endChunk(); } @@ -108,49 +83,24 @@ struct Encoder encodeData(SerialBinary::kDataFourCC, data, size); } - void encode(nullptr_t) - { - encodeData( - SerialBinary::kNullFourCC, - nullptr, 0); - } + void encode(nullptr_t) { encodeData(SerialBinary::kNullFourCC, nullptr, 0); } void encodeBool(bool value) { - encodeData( - value ? SerialBinary::kTrueFourCC : SerialBinary::kFalseFourCC, - nullptr, 0); + encodeData(value ? SerialBinary::kTrueFourCC : SerialBinary::kFalseFourCC, nullptr, 0); } - void encode(Int32 value) - { - encodeData(SerialBinary::kInt32FourCC, &value, sizeof(value)); - } + void encode(Int32 value) { encodeData(SerialBinary::kInt32FourCC, &value, sizeof(value)); } - void encode(UInt32 value) - { - encodeData(SerialBinary::kUInt32FourCC, &value, sizeof(value)); - } + void encode(UInt32 value) { encodeData(SerialBinary::kUInt32FourCC, &value, sizeof(value)); } - void encode(Int64 value) - { - encodeData(SerialBinary::kInt64FourCC, &value, sizeof(value)); - } + void encode(Int64 value) { encodeData(SerialBinary::kInt64FourCC, &value, sizeof(value)); } - void encode(UInt64 value) - { - encodeData(SerialBinary::kUInt64FourCC, &value, sizeof(value)); - } + void encode(UInt64 value) { encodeData(SerialBinary::kUInt64FourCC, &value, sizeof(value)); } - void encode(float value) - { - encodeData(SerialBinary::kFloat32FourCC, &value, sizeof(value)); - } + void encode(float value) { encodeData(SerialBinary::kFloat32FourCC, &value, sizeof(value)); } - void encode(double value) - { - encodeData(SerialBinary::kFloat64FourCC, &value, sizeof(value)); - } + void encode(double value) { encodeData(SerialBinary::kFloat64FourCC, &value, sizeof(value)); } void encodeString(String const& value) { @@ -159,10 +109,7 @@ struct Encoder } - void encode(String const& value) - { - encodeString(value); - } + void encode(String const& value) { encodeString(value); } struct WithArray { @@ -179,14 +126,10 @@ struct Encoder encoder->beginArray(typeCode); } - ~WithArray() - { - _encoder->endArray(); - } + ~WithArray() { _encoder->endArray(); } private: Encoder* _encoder; - }; struct WithObject @@ -204,10 +147,7 @@ struct Encoder encoder->beginObject(typeCode); } - ~WithObject() - { - _encoder->endObject(); - } + ~WithObject() { _encoder->endObject(); } private: Encoder* _encoder; @@ -228,10 +168,7 @@ struct Encoder encoder->beginKeyValuePair(typeCode); } - ~WithKeyValuePair() - { - _encoder->endKeyValuePair(); - } + ~WithKeyValuePair() { _encoder->endKeyValuePair(); } private: Encoder* _encoder; @@ -244,17 +181,11 @@ struct Encoder RiffContainer _riff; public: - RiffContainer* getRIFF() { - return &_riff; - } + RiffContainer* getRIFF() { return &_riff; } - RiffContainer::Chunk* getRIFFChunk() { - return _riff.getCurrentChunk(); - } + RiffContainer::Chunk* getRIFFChunk() { return _riff.getCurrentChunk(); } - void setRIFFChunk(RiffContainer::Chunk* chunk) { - _riff.setCurrentChunk(chunk); - } + void setRIFFChunk(RiffContainer::Chunk* chunk) { _riff.setCurrentChunk(chunk); } }; struct Decoder @@ -262,7 +193,8 @@ struct Decoder public: Decoder(RiffContainer::Chunk* chunk) : _chunk(chunk) - {} + { + } bool decodeBool() { @@ -300,7 +232,7 @@ struct Decoder String value; value.appendRepeatedChar(' ', size); - dataChunk->getPayload((char*) value.getBuffer()); + dataChunk->getPayload((char*)value.getBuffer()); _chunk = _chunk->m_next; return value; @@ -334,42 +266,20 @@ struct Decoder return value; } - Int64 decodeInt64() - { - return _decodeSimpleValue(SerialBinary::kInt64FourCC); - } + Int64 decodeInt64() { return _decodeSimpleValue(SerialBinary::kInt64FourCC); } - UInt64 decodeUInt64() - { - return _decodeSimpleValue(SerialBinary::kUInt64FourCC); - } + UInt64 decodeUInt64() { return _decodeSimpleValue(SerialBinary::kUInt64FourCC); } - Int32 decodeInt32() - { - return _decodeSimpleValue(SerialBinary::kInt32FourCC); - } + Int32 decodeInt32() { return _decodeSimpleValue(SerialBinary::kInt32FourCC); } - UInt32 decodeUInt32() - { - return _decodeSimpleValue(SerialBinary::kUInt32FourCC); - } + UInt32 decodeUInt32() { return _decodeSimpleValue(SerialBinary::kUInt32FourCC); } - float decodeFloat32() - { - return _decodeSimpleValue(SerialBinary::kFloat32FourCC); - } + float decodeFloat32() { return _decodeSimpleValue(SerialBinary::kFloat32FourCC); } - double decodeFloat64() - { - return _decodeSimpleValue(SerialBinary::kFloat64FourCC); - } + double decodeFloat64() { return _decodeSimpleValue(SerialBinary::kFloat64FourCC); } - - FourCC getTag() - { - return _chunk ? _chunk->m_fourCC : 0; - } + FourCC getTag() { return _chunk ? _chunk->m_fourCC : 0; } Int32 _decodeImpl(Int32*) { return decodeInt32(); } UInt32 _decodeImpl(UInt32*) { return decodeUInt32(); } @@ -389,7 +299,7 @@ struct Decoder template void decode(T& outValue) { - outValue = _decodeImpl((T*) nullptr); + outValue = _decodeImpl((T*)nullptr); } void beginArray(FourCC typeCode = SerialBinary::kArrayFourCC) @@ -465,15 +375,14 @@ struct Decoder _chunk = found->getFirstContainedChunk(); } - bool hasElements() - { - return _chunk != nullptr; - } + bool hasElements() { return _chunk != nullptr; } bool isNull() { - if (_chunk == nullptr) return true; - if (getTag() == SerialBinary::kNullFourCC) return true; + if (_chunk == nullptr) + return true; + if (getTag() == SerialBinary::kNullFourCC) + return true; return false; } @@ -506,15 +415,11 @@ struct Decoder decoder.beginArray(typeCode); } - ~WithArray() - { - _decoder._chunk = _saved->m_next; - } + ~WithArray() { _decoder._chunk = _saved->m_next; } private: RiffContainer::Chunk* _saved; Decoder& _decoder; - }; struct WithObject @@ -534,10 +439,7 @@ struct Decoder decoder.beginObject(typeCode); } - ~WithObject() - { - _decoder._chunk = _saved->m_next; - } + ~WithObject() { _decoder._chunk = _saved->m_next; } private: RiffContainer::Chunk* _saved; @@ -561,10 +463,7 @@ struct Decoder _decoder.beginKeyValuePair(typeCode); } - ~WithKeyValuePair() - { - _decoder._chunk = _saved->m_next; - } + ~WithKeyValuePair() { _decoder._chunk = _saved->m_next; } private: RiffContainer::Chunk* _saved; @@ -581,10 +480,7 @@ struct Decoder _decoder.beginProperty(typeCode); } - ~WithProperty() - { - _decoder._chunk = _saved->m_next; - } + ~WithProperty() { _decoder._chunk = _saved->m_next; } private: RiffContainer::Chunk* _saved; @@ -593,10 +489,7 @@ struct Decoder RiffContainer::Chunk* getCursor() { return _chunk; } - void setCursor(RiffContainer::Chunk* chunk) - { - _chunk = chunk; - } + void setCursor(RiffContainer::Chunk* chunk) { _chunk = chunk; } private: RiffContainer::Chunk* _chunk = nullptr; diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp index eb022cedcef..e45311abc75 100644 --- a/source/slang/slang-syntax.cpp +++ b/source/slang/slang-syntax.cpp @@ -15,32 +15,36 @@ bool SyntaxClassBase::isSubClassOf(SyntaxClassBase const& other) const auto otherInfo = other.getInfo(); if (!selfInfo || !otherInfo) return false; - return unsigned((int)selfInfo->firstTag - (int)otherInfo->firstTag) < unsigned(otherInfo->tagCount); + return unsigned((int)selfInfo->firstTag - (int)otherInfo->firstTag) < + unsigned(otherInfo->tagCount); } UnownedTerminatedStringSlice SyntaxClassBase::getName() const { - return _info ? UnownedTerminatedStringSlice(_info->name) : UnownedTerminatedStringSlice(); + return _info ? UnownedTerminatedStringSlice(_info->name) : UnownedTerminatedStringSlice(); } void* SyntaxClassBase::createInstanceImpl(ASTBuilder* astBuilder) const { - if (!_info) return nullptr; - if (!_info->createFunc) return nullptr; + if (!_info) + return nullptr; + if (!_info->createFunc) + return nullptr; return _info->createFunc(astBuilder); } void SyntaxClassBase::destructInstanceImpl(void* instance) const { - if (!_info) return; - if (!_info->destructFunc) return; + if (!_info) + return; + if (!_info->destructFunc) + return; return _info->destructFunc(instance); } - /* static */ const TypeExp TypeExp::empty; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DiagnosticSink impls !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/source/slang/slang-visitor.h b/source/slang/slang-visitor.h index 5c8fa1f25e6..ff913cf3d40 100644 --- a/source/slang/slang-visitor.h +++ b/source/slang/slang-visitor.h @@ -5,8 +5,8 @@ // This file defines the basic "Visitor" pattern for doing dispatch // over the various categories of syntax node. -#include "slang-ast-forward-declarations.h" #include "slang-ast-dispatch.h" +#include "slang-ast-forward-declarations.h" #include "slang-syntax.h" namespace Slang @@ -93,12 +93,16 @@ struct TypeVisitor { Result dispatch(Type* type) { - return ASTNodeDispatcher::dispatch(type, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + type, + [&](auto obj) { return _dispatchImpl(obj); }); } Result dispatchType(Type* type) { - return ASTNodeDispatcher::dispatch(type, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + type, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: @@ -136,7 +140,9 @@ struct ExprVisitor { Result dispatch(Expr* expr) { - return ASTNodeDispatcher::dispatch(expr, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + expr, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: @@ -174,7 +180,9 @@ struct StmtVisitor { Result dispatch(Stmt* stmt) { - return ASTNodeDispatcher::dispatch(stmt, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + stmt, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: @@ -195,7 +203,9 @@ struct DeclVisitor { Result dispatch(DeclBase* decl) { - return ASTNodeDispatcher::dispatch(decl, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + decl, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: @@ -234,7 +244,9 @@ struct ModifierVisitor { Result dispatch(Modifier* modifier) { - return ASTNodeDispatcher::dispatch(modifier, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + modifier, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: @@ -255,7 +267,9 @@ struct ValVisitor : TypeVisitor { Result dispatch(Val* val) { - return ASTNodeDispatcher::dispatch(val, [&](auto obj) { return _dispatchImpl(obj); }); + return ASTNodeDispatcher::dispatch( + val, + [&](auto obj) { return _dispatchImpl(obj); }); } #if 0 // FIDDLE TEMPLATE: diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 96a32068fef..99457647d25 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -658,8 +658,10 @@ SlangResult Session::saveBuiltinModule( // // TODO(tfoley): why can't the file system let us open the file for output? // - SLANG_RETURN_ON_FAIL( - fileSystem->saveFile(moduleFileName.getBuffer(), contents.getBuffer(), contents.getCount())); + SLANG_RETURN_ON_FAIL(fileSystem->saveFile( + moduleFileName.getBuffer(), + contents.getBuffer(), + contents.getCount())); // And finally, we can ask the archive file system to serialize itself // out as a blob of bytes, which yields the final serialized representation @@ -724,10 +726,8 @@ SlangResult Session::_readBuiltinModule( RefPtr sourceLocReader; if (auto debugChunk = findDebugChunk(moduleChunk.ptr())) { - SLANG_RETURN_ON_FAIL(readSourceLocationsFromDebugChunk( - debugChunk, - sourceManager, - sourceLocReader)); + SLANG_RETURN_ON_FAIL( + readSourceLocationsFromDebugChunk(debugChunk, sourceManager, sourceLocReader)); } // At this point we create the `Module` object that will @@ -1596,7 +1596,8 @@ slang::IModule* Linkage::loadModuleFromBlob( pathInfo = PathInfo::makeNormal(pathStr, cannonicalPath); } } - RefPtr module = loadModuleImpl(name, pathInfo, source, SourceLoc(), &sink, nullptr, blobType); + RefPtr module = + loadModuleImpl(name, pathInfo, source, SourceLoc(), &sink, nullptr, blobType); sink.getBlobIfNeeded(outDiagnostics); return asExternal(module.detach()); } @@ -4170,12 +4171,7 @@ RefPtr Linkage::findOrLoadSerializedModuleForModuleLibrary( // will go ahead and load the module from the serialized form. // PathInfo filePathInfo; - return loadSerializedModule( - moduleName, - modulePathInfo, - moduleChunk, - SourceLoc(), - sink); + return loadSerializedModule(moduleName, modulePathInfo, moduleChunk, SourceLoc(), sink); } RefPtr Linkage::loadSerializedModule( @@ -4210,11 +4206,8 @@ RefPtr Linkage::loadSerializedModule( mapNameToLoadedModules.add(moduleName, module); try { - if (SLANG_FAILED(loadSerializedModuleContents( - module, - moduleFilePathInfo, - moduleChunk, - sink))) + if (SLANG_FAILED( + loadSerializedModuleContents(module, moduleFilePathInfo, moduleChunk, sink))) { mapPathToLoadedModule.remove(mostUniqueIdentity); mapNameToLoadedModules.remove(moduleName); @@ -4282,12 +4275,8 @@ RefPtr Linkage::loadBinaryModuleImpl( // If everything seems reasonable, then we will go ahead and load // the module more completely from that serialized representation. // - RefPtr module = loadSerializedModule( - moduleName, - moduleFilePathInfo, - moduleChunkRef, - requestingLoc, - sink); + RefPtr module = + loadSerializedModule(moduleName, moduleFilePathInfo, moduleChunkRef, requestingLoc, sink); return module; } @@ -4316,12 +4305,7 @@ RefPtr Linkage::loadModuleImpl( switch (blobType) { case ModuleBlobType::IR: - return loadBinaryModuleImpl( - moduleName, - modulePathInfo, - moduleBlob, - requestingLoc, - sink); + return loadBinaryModuleImpl(moduleName, modulePathInfo, moduleBlob, requestingLoc, sink); case ModuleBlobType::Source: return loadSourceModuleImpl( @@ -4594,24 +4578,21 @@ RefPtr Linkage::findOrImportModule( // auto defaultSourceFileName = getFileNameFromModuleName(moduleName, false); auto alternativeSourceFileName = getFileNameFromModuleName(moduleName, true); - String sourceFileNamesToTry[] = { defaultSourceFileName, alternativeSourceFileName }; + String sourceFileNamesToTry[] = {defaultSourceFileName, alternativeSourceFileName}; // We are going to look for the candidate file using the same // logic that would be used for a preprocessor `#include`, // so we set up the necessary state. // - IncludeSystem includeSystem( - &getSearchDirectories(), - getFileSystemExt(), - getSourceManager()); + IncludeSystem includeSystem(&getSearchDirectories(), getFileSystemExt(), getSourceManager()); // Just like with a `#include`, the search will take into // account the path to the file where the request to import // this module came from (e.g. the source file with the // `import` declaration), if such a path is available. // - PathInfo requestingPathInfo = getSourceManager()->getPathInfo( - requestingLoc, SourceLocType::Actual); + PathInfo requestingPathInfo = + getSourceManager()->getPathInfo(requestingLoc, SourceLocType::Actual); for (auto type : typesToTry) { @@ -4647,7 +4628,7 @@ RefPtr Linkage::findOrImportModule( // PathInfo filePathInfo; if (SLANG_FAILED( - includeSystem.findFile(fileName, requestingPathInfo.foundPath, filePathInfo))) + includeSystem.findFile(fileName, requestingPathInfo.foundPath, filePathInfo))) { // If we failed to find the file at this step, we // will continue the search for our other options. @@ -4672,8 +4653,8 @@ RefPtr Linkage::findOrImportModule( // will re-use the existing module if we find one here. // if (mapPathToLoadedModule.tryGetValue( - filePathInfo.getMostUniqueIdentity(), - previouslyLoadedModule)) + filePathInfo.getMostUniqueIdentity(), + previouslyLoadedModule)) { // TODO: If we find a previously-loaded module at this step, // then we should probably register that module under the @@ -4734,8 +4715,7 @@ RefPtr Linkage::findOrImportModule( // list of the file names that were tried, if // nothing was even found via the include system). // - sink->diagnose( - requestingLoc, Diagnostics::cannotOpenFile, defaultSourceFileName); + sink->diagnose(requestingLoc, Diagnostics::cannotOpenFile, defaultSourceFileName); // If the attempt to import the module failed, then // we will stick a null pointer into the map of loaded @@ -6559,10 +6539,8 @@ SlangResult Linkage::loadSerializedModuleContents( RefPtr sourceLocReader; if (auto debugChunk = findDebugChunk(moduleChunk.ptr())) { - SLANG_RETURN_ON_FAIL(readSourceLocationsFromDebugChunk( - debugChunk, - sourceManager, - sourceLocReader)); + SLANG_RETURN_ON_FAIL( + readSourceLocationsFromDebugChunk(debugChunk, sourceManager, sourceLocReader)); } auto astChunk = moduleChunk.findAST(); @@ -6598,13 +6576,15 @@ SlangResult Linkage::loadSerializedModuleContents( // SourceLoc serializedModuleLoc; { - auto sourceFile = sourceManager->findSourceFileByPathRecursively(moduleFilePathInfo.foundPath); + auto sourceFile = + sourceManager->findSourceFileByPathRecursively(moduleFilePathInfo.foundPath); if (!sourceFile) { sourceFile = sourceManager->createSourceFileWithString(moduleFilePathInfo, String()); sourceManager->addSourceFile(moduleFilePathInfo.getMostUniqueIdentity(), sourceFile); } - auto sourceView = sourceManager->createSourceView(sourceFile, &moduleFilePathInfo, SourceLoc()); + auto sourceView = + sourceManager->createSourceView(sourceFile, &moduleFilePathInfo, SourceLoc()); serializedModuleLoc = sourceView->getRange().begin; } @@ -6620,11 +6600,7 @@ SlangResult Linkage::loadSerializedModuleContents( module->setModuleDecl(moduleDecl); RefPtr irModule; - SLANG_RETURN_ON_FAIL(decodeModuleIR( - irModule, - irChunk, - session, - sourceLocReader)); + SLANG_RETURN_ON_FAIL(decodeModuleIR(irModule, irChunk, session, sourceLocReader)); module->setIRModule(irModule); // The handling of file dependencies is complicated, because of @@ -6637,7 +6613,7 @@ SlangResult Linkage::loadSerializedModuleContents( module->clearFileDependency(); String moduleSourcePath = moduleFilePathInfo.foundPath; bool isFirst = true; - for(auto depenencyFileChunk : moduleChunk.getFileDependencies()) + for (auto depenencyFileChunk : moduleChunk.getFileDependencies()) { auto encodedDependencyFilePath = depenencyFileChunk.getValue();