File: Compiler\StackTraceEmissionPolicy.cs
Web Access
Project: src\src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Internal.TypeSystem;

namespace ILCompiler
{
    /// <summary>
    /// Represents a stack trace emission policy.
    /// </summary>
    public abstract class StackTraceEmissionPolicy
    {
        public abstract MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method);
    }

    public class NoStackTraceEmissionPolicy : StackTraceEmissionPolicy
    {
        public override MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method)
        {
            return default;
        }
    }

    /// <summary>
    /// Stack trace emission policy that ensures presence of stack trace metadata for all
    /// <see cref="Internal.TypeSystem.Ecma.EcmaMethod"/>-based methods.
    /// </summary>
    public class EcmaMethodStackTraceEmissionPolicy : StackTraceEmissionPolicy
    {
        private readonly MethodStackTraceVisibilityFlags _flags;

        public EcmaMethodStackTraceEmissionPolicy(bool includeLineNumbers)
        {
            _flags = includeLineNumbers ? MethodStackTraceVisibilityFlags.HasLineNumbers : 0;
        }

        public override MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method)
        {
            MethodStackTraceVisibilityFlags result = _flags;

            if (method.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute")
                || (method.OwningType is MetadataType mdType && mdType.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute"))
                || (method is Internal.IL.Stubs.ILStubMethod) || method.IsAsyncThunk()) // see MethodDesc::IsDiagnosticsHidden() in src/coreclr/vm/method.inl
            {
                result |= MethodStackTraceVisibilityFlags.IsHidden;
            }

            return (method.GetTypicalMethodDefinition() is Internal.TypeSystem.Ecma.EcmaMethod || (method.IsAsync && method.IsAsyncCall()))
                ? result | MethodStackTraceVisibilityFlags.HasMetadata
                : result;
        }
    }

    [Flags]
    public enum MethodStackTraceVisibilityFlags
    {
        HasMetadata = 0x1,
        IsHidden = 0x2,
        HasLineNumbers = 0x4,
    }
}