Editor/Prism/Compiler/Ir/IrFunction.cs

Represents a function in the compiler IR emitted module, including name, return type, parameters, body block, stage, attributes and helpers for producing an HLSL signature.

File Access
using Editor.Prism.Core;

namespace Editor.Prism.Compiler.Ir;

/// <summary>
/// A function in the emitted module: an entry point (<c>MainVs</c>, <c>MainPs</c>, <c>MainCs</c>) or
/// a generated helper. Entry points carry the stage they belong to and the semantic of their result.
/// </summary>
public sealed class IrFunction
{
	/// <summary>Declare a function.</summary>
	public IrFunction( string name, ShaderType returnType )
	{
		Name = name;
		ReturnType = returnType;
	}

	/// <summary>Emitted function name.</summary>
	public string Name { get; }

	/// <summary>Return type.</summary>
	public ShaderType ReturnType { get; }

	/// <summary>Name of the returned struct type, when <see cref="ReturnType"/> is a struct.</summary>
	public string ReturnStruct { get; init; }

	/// <summary>Parameters, in order.</summary>
	public List<HelperParam> Parameters { get; } = new();

	/// <summary>The body.</summary>
	public IrBlock Body { get; } = new();

	/// <summary>The stage this function belongs to, or <see cref="ShaderStage.None"/> for a free helper.</summary>
	public ShaderStage Stage { get; init; }

	/// <summary>True when this is a shader entry point.</summary>
	public bool IsEntryPoint { get; init; }

	/// <summary>Semantic applied to the return value, e.g. <c>SV_Target0</c>.</summary>
	public string ReturnSemantic { get; init; }

	/// <summary>
	/// Attributes to emit above the signature, e.g. <c>[numthreads(8,8,1)]</c> or, for Slang,
	/// <c>[shader("pixel")]</c>.
	/// </summary>
	public List<string> Attributes { get; } = new();

	/// <summary>False when the function has side effects.</summary>
	public bool Pure { get; init; } = true;

	/// <summary>The signature line in HLSL, without a body.</summary>
	public string SignatureHlsl
	{
		get
		{
			var parameters = string.Join( ", ", Parameters.Select( x => x.Hlsl ) );
			var returnType = string.IsNullOrEmpty( ReturnStruct ) ? ReturnType.Hlsl : ReturnStruct;
			var semantic = string.IsNullOrEmpty( ReturnSemantic ) ? string.Empty : $" : {ReturnSemantic}";

			return $"{returnType} {Name}( {parameters} ){semantic}";
		}
	}

	/// <inheritdoc/>
	public override string ToString() => SignatureHlsl;
}