Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/coreclr/tools/aot/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Linker port settings:
# A newline ending every file
# Use tabs as indentation
[ILLink.Shared/**.cs]
indent_style = tab
indent_size = 4
csharp_new_line_before_open_brace = types,methods
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true

csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_name_and_open_parenthesis = true
csharp_space_between_method_call_name_and_opening_parenthesis = true
csharp_space_before_open_square_brackets = false
csharp_space_after_cast = true

csharp_indent_switch_labels = false

# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true

# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void TestDependencyGraphInvariants(EcmaMethod method)
UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager(compilationGroup, context,
new FullyBlockedMetadataBlockingPolicy(), new FullyBlockedManifestResourceBlockingPolicy(),
null, new NoStackTraceEmissionPolicy(), new NoDynamicInvokeThunkGenerationPolicy(),
new Dataflow.FlowAnnotations(Logger.Null, ilProvider), UsageBasedMetadataGenerationOptions.None,
new ILLink.Shared.TrimAnalysis.FlowAnnotations(Logger.Null, ilProvider), UsageBasedMetadataGenerationOptions.None,
Logger.Null, Array.Empty<KeyValuePair<string, bool>>(), Array.Empty<string>(), Array.Empty<string>());

CompilationBuilder builder = new RyuJitCompilationBuilder(context, compilationGroup)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// 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 ILCompiler.Dataflow;
using ILLink.Shared.DataFlow;
using Internal.TypeSystem;

using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.SingleValue>;

#nullable enable

namespace ILLink.Shared.TrimAnalysis
{
partial record ArrayValue
{
public static MultiValue Create(MultiValue size, TypeDesc 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, TypeDesc elementType)
{
return new MultiValue(new ArrayValue(new ConstIntValue(size), elementType));
}

/// <summary>
/// Constructs an array value of the given size
/// </summary>
ArrayValue(SingleValue size, TypeDesc elementType)
{
Size = size;
ElementType = elementType;
IndexValues = new Dictionary<int, ValueBasicBlockPair>();
}

public TypeDesc 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();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using ILCompiler;
using ILCompiler.Logging;

#nullable enable

namespace ILLink.Shared.TrimAnalysis
{
readonly partial struct DiagnosticContext
{
public readonly MessageOrigin Origin;
public readonly bool DiagnosticsEnabled;
readonly Logger _logger;

public DiagnosticContext(in MessageOrigin origin, bool diagnosticsEnabled, Logger logger)
=> (Origin, DiagnosticsEnabled, _logger) = (origin, diagnosticsEnabled, logger);

public partial void AddDiagnostic(DiagnosticId id, params string[] args)
{
if (DiagnosticsEnabled)
_logger.LogWarning(Origin, id, args);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ internal static bool IsInRequiresScope(this MethodDesc method, string requiresAt
method.IsInRequiresScope(requiresAttribute, true);

/// <summary>
/// True if member of a call is considered to be annotated with the Requires... attribute.
/// Doesn't check the associated symbol for overrides and virtual methods because we should warn on mismatched between the property AND the accessors
/// </summary>
/// <param name="method">
/// MethodDesc that is either an overriding member or an overriden/virtual member
/// </param>
/// True if member of a call is considered to be annotated with the Requires... attribute.
/// Doesn't check the associated symbol for overrides and virtual methods because we should warn on mismatched between the property AND the accessors
/// </summary>
/// <param name="method">
/// MethodDesc that is either an overriding member or an overriden/virtual member
/// </param>
internal static bool IsOverrideInRequiresScope(this MethodDesc method, string requiresAttribute) =>
method.IsInRequiresScope(requiresAttribute, false);

Expand Down Expand Up @@ -185,10 +185,10 @@ internal static bool DoesPropertyRequire(this PropertyPseudoDesc property, strin
TryGetRequiresAttribute(property, requiresAttribute, out attribute);

/// <summary>
/// Determines if member requires (and thus any usage of such method should be warned about).
/// </summary>
/// <remarks>Unlike <see cref="IsInRequiresScope(MethodDesc, string)"/> only static methods
/// and .ctors are reported as requires when the declaring type has Requires on it.</remarks>
/// Determines if member requires (and thus any usage of such method should be warned about).
/// </summary>
/// <remarks>Unlike <see cref="IsInRequiresScope(MethodDesc, string)"/> only static methods
/// and .ctors are reported as requires when the declaring type has Requires on it.</remarks>
internal static bool DoesMemberRequire(this TypeSystemEntity member, string requiresAttribute, [NotNullWhen(returnValue: true)] out CustomAttributeValue<TypeDesc>? attribute)
{
attribute = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public static IEnumerable<EventPseudoDesc> GetEventsOnTypeHierarchy(this TypeDes
type = type.BaseType;
onBaseType = true;
}

while (type != null)
{
if (type.GetTypeDefinition() is not EcmaType ecmaType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static bool IsPublic(this MethodDesc method)
public static bool IsPublic(this FieldDesc field)
{
return field.GetTypicalFieldDefinition() is EcmaField ecmaField
&& (ecmaField.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
&& (ecmaField.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
}

public static bool IsPrivate(this MethodDesc method)
Expand Down
Original file line number Diff line number Diff line change
@@ -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 ILCompiler;
using ILCompiler.Dataflow;
using ILLink.Shared.DataFlow;
using Internal.TypeSystem;

#nullable enable

namespace ILLink.Shared.TrimAnalysis
{

/// <summary>
/// A representation of a field. Typically a result of ldfld.
/// </summary>
sealed partial record FieldValue : IValueWithStaticType
{
public FieldValue(FieldDesc field, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
{
StaticType = field.FieldType;
Field = field;
DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
}

public readonly FieldDesc Field;

public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes { get; }

public override IEnumerable<string> GetDiagnosticArgumentsForAnnotationMismatch()
=> new string[] { Field.GetDisplayName() };

public TypeDesc? StaticType { get; }

public override SingleValue DeepCopy() => this; // This value is immutable

public override string ToString() => this.ValueToString(Field, DynamicallyAccessedMemberTypes);
}
}
Loading