Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Schuster <36744439+jtschuster@users.noreply.github.com>2022-04-01 20:41:17 +0300
committerGitHub <noreply@github.com>2022-04-01 20:41:17 +0300
commit987a86e2e96a06e01f5d84c416c3c5f70e7ecbd6 (patch)
tree1b7785d4e155a5ac0302221c6080f72b96375484
parent4f0d349e43a71d44ef71339293701fcfc2da997e (diff)
Break up ValueNode.cs so each Value has it's own file (#2713)
* Break up ValueNode.cs so each Value has it's own file * Update ValueNode.cs namespace
-rw-r--r--src/linker/Linker.Dataflow/ArrayValue.cs121
-rw-r--r--src/linker/Linker.Dataflow/FieldValue.cs41
-rw-r--r--src/linker/Linker.Dataflow/GenericParameterValue.cs35
-rw-r--r--src/linker/Linker.Dataflow/MethodParameterValue.cs49
-rw-r--r--src/linker/Linker.Dataflow/MethodReturnValue.cs39
-rw-r--r--src/linker/Linker.Dataflow/MethodThisParameterValue.cs40
-rw-r--r--src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs2
-rw-r--r--src/linker/Linker.Dataflow/RuntimeMethodHandleValue.cs24
-rw-r--r--src/linker/Linker.Dataflow/SingleValueExtensions.cs87
-rw-r--r--src/linker/Linker.Dataflow/ValueNode.cs348
10 files changed, 437 insertions, 349 deletions
diff --git a/src/linker/Linker.Dataflow/ArrayValue.cs b/src/linker/Linker.Dataflow/ArrayValue.cs
new file mode 100644
index 000000000..884e5cd7e
--- /dev/null
+++ b/src/linker/Linker.Dataflow/ArrayValue.cs
@@ -0,0 +1,121 @@
+// 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 System.Collections.Generic;
+using System.Text;
+using ILLink.Shared.DataFlow;
+using Mono.Cecil;
+using Mono.Linker.Dataflow;
+using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.SingleValue>;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+ partial record ArrayValue
+ {
+ public static MultiValue Create (MultiValue size, TypeReference elementType)
+ {
+ MultiValue result = MultiValueLattice.Top;
+ foreach (var sizeValue in size) {
+ result = MultiValueLattice.Meet (result, new MultiValue (new ArrayValue (sizeValue, elementType)));
+ }
+
+ return result;
+ }
+
+ public static MultiValue Create (int size, TypeReference elementType)
+ {
+ return new MultiValue (new ArrayValue (new ConstIntValue (size), elementType));
+ }
+
+ /// <summary>
+ /// Constructs an array value of the given size
+ /// </summary>
+ ArrayValue (SingleValue size, TypeReference elementType)
+ {
+ Size = size;
+ ElementType = elementType;
+ IndexValues = new Dictionary<int, ValueBasicBlockPair> ();
+ }
+
+ public TypeReference ElementType { get; }
+ public Dictionary<int, ValueBasicBlockPair> IndexValues { get; }
+
+ public partial bool TryGetValueByIndex (int index, out MultiValue value)
+ {
+ if (IndexValues.TryGetValue (index, out var valuePair)) {
+ value = valuePair.Value;
+ return true;
+ }
+
+ value = default;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return HashCode.Combine (GetType ().GetHashCode (), Size);
+ }
+
+ public bool Equals (ArrayValue? otherArr)
+ {
+ if (otherArr == null)
+ return false;
+
+ bool equals = Size.Equals (otherArr.Size);
+ equals &= IndexValues.Count == otherArr.IndexValues.Count;
+ if (!equals)
+ return false;
+
+ // If both sets T and O are the same size and "T intersect O" is empty, then T == O.
+ HashSet<KeyValuePair<int, ValueBasicBlockPair>> thisValueSet = new (IndexValues);
+ HashSet<KeyValuePair<int, ValueBasicBlockPair>> otherValueSet = new (otherArr.IndexValues);
+ thisValueSet.ExceptWith (otherValueSet);
+ return thisValueSet.Count == 0;
+ }
+
+ public override SingleValue DeepCopy ()
+ {
+ var newValue = new ArrayValue (Size.DeepCopy (), ElementType);
+ foreach (var kvp in IndexValues) {
+ newValue.IndexValues.Add (kvp.Key, new ValueBasicBlockPair (kvp.Value.Value.Clone (), kvp.Value.BasicBlockIndex));
+ }
+
+ return newValue;
+ }
+
+ public override string ToString ()
+ {
+ StringBuilder result = new ();
+ result.Append ("Array Size:");
+ result.Append (this.ValueToString (Size));
+
+ result.Append (", Values:(");
+ bool first = true;
+ foreach (var element in IndexValues) {
+ if (!first) {
+ result.Append (",");
+ first = false;
+ }
+
+ result.Append ("(");
+ result.Append (element.Key);
+ result.Append (",(");
+ bool firstValue = true;
+ foreach (var v in element.Value.Value) {
+ if (firstValue) {
+ result.Append (",");
+ firstValue = false;
+ }
+
+ result.Append (v.ToString ());
+ }
+ result.Append ("))");
+ }
+ result.Append (')');
+
+ return result.ToString ();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/FieldValue.cs b/src/linker/Linker.Dataflow/FieldValue.cs
new file mode 100644
index 000000000..416315128
--- /dev/null
+++ b/src/linker/Linker.Dataflow/FieldValue.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using ILLink.Shared.DataFlow;
+using Mono.Linker;
+using Mono.Linker.Dataflow;
+using FieldDefinition = Mono.Cecil.FieldDefinition;
+using TypeDefinition = Mono.Cecil.TypeDefinition;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+
+ /// <summary>
+ /// A representation of a field. Typically a result of ldfld.
+ /// </summary>
+ sealed partial record FieldValue : IValueWithStaticType
+ {
+ public FieldValue (TypeDefinition? staticType, FieldDefinition fieldToLoad, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
+ {
+ StaticType = staticType;
+ Field = fieldToLoad;
+ DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
+ }
+
+ public readonly FieldDefinition Field;
+
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
+
+ public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
+ => new string[] { Field.GetDisplayName () };
+
+ public TypeDefinition? StaticType { get; }
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (Field, DynamicallyAccessedMemberTypes);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/GenericParameterValue.cs b/src/linker/Linker.Dataflow/GenericParameterValue.cs
new file mode 100644
index 000000000..7f6e104b1
--- /dev/null
+++ b/src/linker/Linker.Dataflow/GenericParameterValue.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using ILLink.Shared.DataFlow;
+using Mono.Linker.Dataflow;
+using GenericParameter = Mono.Cecil.GenericParameter;
+
+namespace ILLink.Shared.TrimAnalysis
+{
+ /// <summary>
+ /// This is a System.Type value which represents generic parameter (basically result of typeof(T))
+ /// Its actual type is unknown, but it can have annotations.
+ /// </summary>
+ partial record GenericParameterValue
+ {
+ public GenericParameterValue (GenericParameter genericParameter, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
+ {
+ GenericParameter = new (genericParameter);
+ DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
+ }
+
+ public partial bool HasDefaultConstructorConstraint () => GenericParameter.GenericParameter.HasDefaultConstructorConstraint;
+
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
+
+ public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
+ => new string[] { GenericParameter.GenericParameter.Name, DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName (GenericParameter.GenericParameter) };
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (GenericParameter, DynamicallyAccessedMemberTypes);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/MethodParameterValue.cs b/src/linker/Linker.Dataflow/MethodParameterValue.cs
new file mode 100644
index 000000000..020857223
--- /dev/null
+++ b/src/linker/Linker.Dataflow/MethodParameterValue.cs
@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using ILLink.Shared.DataFlow;
+using Mono.Cecil;
+using Mono.Linker.Dataflow;
+using TypeDefinition = Mono.Cecil.TypeDefinition;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+
+ /// <summary>
+ /// A value that came from a method parameter - such as the result of a ldarg.
+ /// </summary>
+ partial record MethodParameterValue : IValueWithStaticType
+ {
+ public MethodParameterValue (TypeDefinition? staticType, MethodDefinition method, int parameterIndex, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
+ {
+ StaticType = staticType;
+ Method = method;
+ ParameterIndex = parameterIndex;
+ DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
+ }
+
+ public readonly MethodDefinition Method;
+
+ /// <summary>
+ /// This is the index of non-implicit parameter - so the index into MethodDefinition.Parameters array.
+ /// It's NOT the IL parameter index which could be offset by 1 if the method has an implicit this.
+ /// </summary>
+ public readonly int ParameterIndex;
+
+ public ParameterDefinition ParameterDefinition => Method.Parameters[ParameterIndex];
+
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
+
+ public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
+ => new string[] { DiagnosticUtilities.GetParameterNameForErrorMessage (ParameterDefinition), DiagnosticUtilities.GetMethodSignatureDisplayName (Method) };
+
+ public TypeDefinition? StaticType { get; }
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (Method, ParameterIndex, DynamicallyAccessedMemberTypes);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/MethodReturnValue.cs b/src/linker/Linker.Dataflow/MethodReturnValue.cs
new file mode 100644
index 000000000..10414a670
--- /dev/null
+++ b/src/linker/Linker.Dataflow/MethodReturnValue.cs
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using ILLink.Shared.DataFlow;
+using Mono.Cecil;
+using Mono.Linker.Dataflow;
+using TypeDefinition = Mono.Cecil.TypeDefinition;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+ /// <summary>
+ /// Return value from a method
+ /// </summary>
+ partial record MethodReturnValue : IValueWithStaticType
+ {
+ public MethodReturnValue (TypeDefinition? staticType, MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
+ {
+ StaticType = staticType;
+ Method = method;
+ DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
+ }
+
+ public readonly MethodDefinition Method;
+
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
+
+ public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
+ => new string[] { DiagnosticUtilities.GetMethodSignatureDisplayName (Method) };
+
+ public TypeDefinition? StaticType { get; }
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (Method, DynamicallyAccessedMemberTypes);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/MethodThisParameterValue.cs b/src/linker/Linker.Dataflow/MethodThisParameterValue.cs
new file mode 100644
index 000000000..e9ded179b
--- /dev/null
+++ b/src/linker/Linker.Dataflow/MethodThisParameterValue.cs
@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using ILLink.Shared.DataFlow;
+using Mono.Cecil;
+using Mono.Linker;
+using Mono.Linker.Dataflow;
+using TypeDefinition = Mono.Cecil.TypeDefinition;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+
+ /// <summary>
+ /// A value that came from the implicit this parameter of a method
+ /// </summary>
+ partial record MethodThisParameterValue : IValueWithStaticType
+ {
+ public MethodThisParameterValue (MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
+ {
+ Method = method;
+ DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
+ }
+
+ public readonly MethodDefinition Method;
+
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
+
+ public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
+ => new string[] { Method.GetDisplayName () };
+
+ public TypeDefinition? StaticType => Method.DeclaringType;
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (Method, DynamicallyAccessedMemberTypes);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
index 992e6f62b..aa58d484f 100644
--- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
+++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
@@ -14,9 +14,7 @@ using ILLink.Shared.TypeSystemProxy;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Linker.Steps;
-
using BindingFlags = System.Reflection.BindingFlags;
-
using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.SingleValue>;
namespace Mono.Linker.Dataflow
diff --git a/src/linker/Linker.Dataflow/RuntimeMethodHandleValue.cs b/src/linker/Linker.Dataflow/RuntimeMethodHandleValue.cs
new file mode 100644
index 000000000..7197b5491
--- /dev/null
+++ b/src/linker/Linker.Dataflow/RuntimeMethodHandleValue.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using ILLink.Shared.DataFlow;
+using Mono.Cecil;
+
+
+namespace ILLink.Shared.TrimAnalysis
+{
+
+ /// <summary>
+ /// This is the System.RuntimeMethodHandle equivalent to a <see cref="SystemReflectionMethodBaseValue"/> node.
+ /// </summary>
+ partial record RuntimeMethodHandleValue
+ {
+ public RuntimeMethodHandleValue (MethodDefinition methodRepresented) => MethodRepresented = methodRepresented;
+
+ public readonly MethodDefinition MethodRepresented;
+
+ public override SingleValue DeepCopy () => this; // This value is immutable
+
+ public override string ToString () => this.ValueToString (MethodRepresented);
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/SingleValueExtensions.cs b/src/linker/Linker.Dataflow/SingleValueExtensions.cs
new file mode 100644
index 000000000..b136c9fef
--- /dev/null
+++ b/src/linker/Linker.Dataflow/SingleValueExtensions.cs
@@ -0,0 +1,87 @@
+// 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 System.Collections.Generic;
+using ILLink.Shared.DataFlow;
+using Mono.Linker.Dataflow;
+
+namespace ILLink.Shared.TrimAnalysis
+{
+ // These are extension methods because we want to allow the use of them on null 'this' pointers.
+ internal static class SingleValueExtensions
+ {
+ /// <summary>
+ /// Returns true if a ValueNode graph contains a cycle
+ /// </summary>
+ /// <param name="node">Node to evaluate</param>
+ /// <param name="seenNodes">Set of nodes previously seen on the current arc. Callers may pass a non-empty set
+ /// to test whether adding that set to this node would create a cycle. Contents will be modified by the walk
+ /// and should not be used by the caller after returning</param>
+ /// <param name="allNodesSeen">Optional. The set of all nodes encountered during a walk after DetectCycle returns</param>
+ /// <returns></returns>
+ public static bool DetectCycle (this SingleValue node, HashSet<SingleValue> seenNodes, HashSet<SingleValue>? allNodesSeen)
+ {
+ if (node == null)
+ return false;
+
+ if (seenNodes.Contains (node))
+ return true;
+
+ seenNodes.Add (node);
+
+ if (allNodesSeen != null) {
+ allNodesSeen.Add (node);
+ }
+
+ bool foundCycle = false;
+ switch (node) {
+ //
+ // Leaf nodes
+ //
+ case UnknownValue:
+ case NullValue:
+ case SystemTypeValue:
+ case RuntimeTypeHandleValue:
+ case KnownStringValue:
+ case ConstIntValue:
+ case MethodParameterValue:
+ case MethodThisParameterValue:
+ case MethodReturnValue:
+ case GenericParameterValue:
+ case RuntimeTypeHandleForGenericParameterValue:
+ case SystemReflectionMethodBaseValue:
+ case RuntimeMethodHandleValue:
+ case FieldValue:
+ break;
+
+ //
+ // Nodes with children
+ //
+ case ArrayValue:
+ ArrayValue av = (ArrayValue) node;
+ foundCycle = av.Size.DetectCycle (seenNodes, allNodesSeen);
+ foreach (ValueBasicBlockPair pair in av.IndexValues.Values) {
+ foreach (var v in pair.Value) {
+ foundCycle |= v.DetectCycle (seenNodes, allNodesSeen);
+ }
+ }
+ break;
+
+ case RuntimeTypeHandleForNullableValueWithDynamicallyAccessedMembers value:
+ foundCycle = value.UnderlyingTypeValue.DetectCycle (seenNodes, allNodesSeen);
+ break;
+
+ case NullableValueWithDynamicallyAccessedMembers value:
+ foundCycle = value.UnderlyingTypeValue.DetectCycle (seenNodes, allNodesSeen);
+ break;
+
+ default:
+ throw new Exception (String.Format ("Unknown node type: {0}", node.GetType ().Name));
+ }
+ seenNodes.Remove (node);
+
+ return foundCycle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/linker/Linker.Dataflow/ValueNode.cs b/src/linker/Linker.Dataflow/ValueNode.cs
index 1cdac92b3..5a0df8f34 100644
--- a/src/linker/Linker.Dataflow/ValueNode.cs
+++ b/src/linker/Linker.Dataflow/ValueNode.cs
@@ -3,354 +3,10 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Text;
-using ILLink.Shared.DataFlow;
-using Mono.Cecil;
-using Mono.Linker;
-using Mono.Linker.Dataflow;
-using FieldDefinition = Mono.Cecil.FieldDefinition;
-using GenericParameter = Mono.Cecil.GenericParameter;
using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.SingleValue>;
-using TypeDefinition = Mono.Cecil.TypeDefinition;
-namespace ILLink.Shared.TrimAnalysis
+namespace Mono.Linker.Dataflow
{
- // These are extension methods because we want to allow the use of them on null 'this' pointers.
- internal static class SingleValueExtensions
- {
- /// <summary>
- /// Returns true if a ValueNode graph contains a cycle
- /// </summary>
- /// <param name="node">Node to evaluate</param>
- /// <param name="seenNodes">Set of nodes previously seen on the current arc. Callers may pass a non-empty set
- /// to test whether adding that set to this node would create a cycle. Contents will be modified by the walk
- /// and should not be used by the caller after returning</param>
- /// <param name="allNodesSeen">Optional. The set of all nodes encountered during a walk after DetectCycle returns</param>
- /// <returns></returns>
- public static bool DetectCycle (this SingleValue node, HashSet<SingleValue> seenNodes, HashSet<SingleValue>? allNodesSeen)
- {
- if (node == null)
- return false;
-
- if (seenNodes.Contains (node))
- return true;
-
- seenNodes.Add (node);
-
- if (allNodesSeen != null) {
- allNodesSeen.Add (node);
- }
-
- bool foundCycle = false;
- switch (node) {
- //
- // Leaf nodes
- //
- case UnknownValue:
- case NullValue:
- case SystemTypeValue:
- case RuntimeTypeHandleValue:
- case KnownStringValue:
- case ConstIntValue:
- case MethodParameterValue:
- case MethodThisParameterValue:
- case MethodReturnValue:
- case GenericParameterValue:
- case RuntimeTypeHandleForGenericParameterValue:
- case SystemReflectionMethodBaseValue:
- case RuntimeMethodHandleValue:
- case FieldValue:
- break;
-
- //
- // Nodes with children
- //
- case ArrayValue:
- ArrayValue av = (ArrayValue) node;
- foundCycle = av.Size.DetectCycle (seenNodes, allNodesSeen);
- foreach (ValueBasicBlockPair pair in av.IndexValues.Values) {
- foreach (var v in pair.Value) {
- foundCycle |= v.DetectCycle (seenNodes, allNodesSeen);
- }
- }
- break;
-
- case RuntimeTypeHandleForNullableValueWithDynamicallyAccessedMembers value:
- foundCycle = value.UnderlyingTypeValue.DetectCycle (seenNodes, allNodesSeen);
- break;
-
- case NullableValueWithDynamicallyAccessedMembers value:
- foundCycle = value.UnderlyingTypeValue.DetectCycle (seenNodes, allNodesSeen);
- break;
-
- default:
- throw new Exception (String.Format ("Unknown node type: {0}", node.GetType ().Name));
- }
- seenNodes.Remove (node);
-
- return foundCycle;
- }
- }
-
- /// <summary>
- /// This is a System.Type value which represents generic parameter (basically result of typeof(T))
- /// Its actual type is unknown, but it can have annotations.
- /// </summary>
- partial record GenericParameterValue
- {
- public GenericParameterValue (GenericParameter genericParameter, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
- {
- GenericParameter = new (genericParameter);
- DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
- }
-
- public partial bool HasDefaultConstructorConstraint () => GenericParameter.GenericParameter.HasDefaultConstructorConstraint;
-
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
-
- public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
- => new string[] { GenericParameter.GenericParameter.Name, DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName (GenericParameter.GenericParameter) };
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (GenericParameter, DynamicallyAccessedMemberTypes);
- }
-
- /// <summary>
- /// This is the System.RuntimeMethodHandle equivalent to a <see cref="SystemReflectionMethodBaseValue"/> node.
- /// </summary>
- partial record RuntimeMethodHandleValue
- {
- public RuntimeMethodHandleValue (MethodDefinition methodRepresented) => MethodRepresented = methodRepresented;
-
- public readonly MethodDefinition MethodRepresented;
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (MethodRepresented);
- }
-
- /// <summary>
- /// A value that came from a method parameter - such as the result of a ldarg.
- /// </summary>
- partial record MethodParameterValue : IValueWithStaticType
- {
- public MethodParameterValue (TypeDefinition? staticType, MethodDefinition method, int parameterIndex, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
- {
- StaticType = staticType;
- Method = method;
- ParameterIndex = parameterIndex;
- DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
- }
-
- public readonly MethodDefinition Method;
-
- /// <summary>
- /// This is the index of non-implicit parameter - so the index into MethodDefinition.Parameters array.
- /// It's NOT the IL parameter index which could be offset by 1 if the method has an implicit this.
- /// </summary>
- public readonly int ParameterIndex;
-
- public ParameterDefinition ParameterDefinition => Method.Parameters[ParameterIndex];
-
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
-
- public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
- => new string[] { DiagnosticUtilities.GetParameterNameForErrorMessage (ParameterDefinition), DiagnosticUtilities.GetMethodSignatureDisplayName (Method) };
-
- public TypeDefinition? StaticType { get; }
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (Method, ParameterIndex, DynamicallyAccessedMemberTypes);
- }
-
- /// <summary>
- /// A value that came from the implicit this parameter of a method
- /// </summary>
- partial record MethodThisParameterValue : IValueWithStaticType
- {
- public MethodThisParameterValue (MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
- {
- Method = method;
- DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
- }
-
- public readonly MethodDefinition Method;
-
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
-
- public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
- => new string[] { Method.GetDisplayName () };
-
- public TypeDefinition? StaticType => Method.DeclaringType;
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (Method, DynamicallyAccessedMemberTypes);
- }
-
- /// <summary>
- /// Return value from a method
- /// </summary>
- partial record MethodReturnValue : IValueWithStaticType
- {
- public MethodReturnValue (TypeDefinition? staticType, MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
- {
- StaticType = staticType;
- Method = method;
- DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
- }
-
- public readonly MethodDefinition Method;
-
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
-
- public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
- => new string[] { DiagnosticUtilities.GetMethodSignatureDisplayName (Method) };
-
- public TypeDefinition? StaticType { get; }
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (Method, DynamicallyAccessedMemberTypes);
- }
-
- /// <summary>
- /// A representation of a field. Typically a result of ldfld.
- /// </summary>
- partial record FieldValue : IValueWithStaticType
- {
- public FieldValue (TypeDefinition? staticType, FieldDefinition fieldToLoad, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
- {
- StaticType = staticType;
- Field = fieldToLoad;
- DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
- }
-
- public readonly FieldDefinition Field;
-
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }
-
- public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch ()
- => new string[] { Field.GetDisplayName () };
-
- public TypeDefinition? StaticType { get; }
-
- public override SingleValue DeepCopy () => this; // This value is immutable
-
- public override string ToString () => this.ValueToString (Field, DynamicallyAccessedMemberTypes);
- }
-
- partial record ArrayValue
- {
- public static MultiValue Create (MultiValue size, TypeReference elementType)
- {
- MultiValue result = MultiValueLattice.Top;
- foreach (var sizeValue in size) {
- result = MultiValueLattice.Meet (result, new MultiValue (new ArrayValue (sizeValue, elementType)));
- }
-
- return result;
- }
-
- public static MultiValue Create (int size, TypeReference elementType)
- {
- return new MultiValue (new ArrayValue (new ConstIntValue (size), elementType));
- }
-
- /// <summary>
- /// Constructs an array value of the given size
- /// </summary>
- ArrayValue (SingleValue size, TypeReference elementType)
- {
- Size = size;
- ElementType = elementType;
- IndexValues = new Dictionary<int, ValueBasicBlockPair> ();
- }
-
- public TypeReference ElementType { get; }
- public Dictionary<int, ValueBasicBlockPair> IndexValues { get; }
-
- public partial bool TryGetValueByIndex (int index, out MultiValue value)
- {
- if (IndexValues.TryGetValue (index, out var valuePair)) {
- value = valuePair.Value;
- return true;
- }
-
- value = default;
- return false;
- }
-
- public override int GetHashCode ()
- {
- return HashCode.Combine (GetType ().GetHashCode (), Size);
- }
-
- public bool Equals (ArrayValue? otherArr)
- {
- if (otherArr == null)
- return false;
-
- bool equals = Size.Equals (otherArr.Size);
- equals &= IndexValues.Count == otherArr.IndexValues.Count;
- if (!equals)
- return false;
-
- // If both sets T and O are the same size and "T intersect O" is empty, then T == O.
- HashSet<KeyValuePair<int, ValueBasicBlockPair>> thisValueSet = new (IndexValues);
- HashSet<KeyValuePair<int, ValueBasicBlockPair>> otherValueSet = new (otherArr.IndexValues);
- thisValueSet.ExceptWith (otherValueSet);
- return thisValueSet.Count == 0;
- }
-
- public override SingleValue DeepCopy ()
- {
- var newValue = new ArrayValue (Size.DeepCopy (), ElementType);
- foreach (var kvp in IndexValues) {
- newValue.IndexValues.Add (kvp.Key, new ValueBasicBlockPair (kvp.Value.Value.Clone (), kvp.Value.BasicBlockIndex));
- }
-
- return newValue;
- }
-
- public override string ToString ()
- {
- StringBuilder result = new ();
- result.Append ("Array Size:");
- result.Append (this.ValueToString (Size));
-
- result.Append (", Values:(");
- bool first = true;
- foreach (var element in IndexValues) {
- if (!first) {
- result.Append (",");
- first = false;
- }
-
- result.Append ("(");
- result.Append (element.Key);
- result.Append (",(");
- bool firstValue = true;
- foreach (var v in element.Value.Value) {
- if (firstValue) {
- result.Append (",");
- firstValue = false;
- }
-
- result.Append (v.ToString ());
- }
- result.Append ("))");
- }
- result.Append (')');
-
- return result.ToString ();
- }
- }
-
- #region ValueNode Collections
public class ValueNodeList : List<MultiValue>
{
public ValueNodeList ()
@@ -390,8 +46,6 @@ namespace ILLink.Shared.TrimAnalysis
return true;
}
}
- #endregion
-
public struct ValueBasicBlockPair
{