1658 lines
59 KiB
C#
1658 lines
59 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using Microsoft.Cci;
|
|
using Microsoft.CodeAnalysis.CSharp.CodeGen;
|
|
using Microsoft.CodeAnalysis.CSharp.Emit;
|
|
using Microsoft.CodeAnalysis.CSharp.Emit.NoPia;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.CodeGen;
|
|
using Microsoft.CodeAnalysis.Emit;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Microsoft.CodeAnalysis.RuntimeMembers;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal sealed class SyntheticBoundNodeFactory
|
|
{
|
|
public class MissingPredefinedMember : Exception
|
|
{
|
|
public Diagnostic Diagnostic { get; }
|
|
|
|
public MissingPredefinedMember(Diagnostic error)
|
|
: base(((object)error).ToString())
|
|
{
|
|
Diagnostic = error;
|
|
}
|
|
}
|
|
|
|
private sealed class SyntheticBinderImpl : BuckStopsHereBinder
|
|
{
|
|
private readonly SyntheticBoundNodeFactory _factory;
|
|
|
|
internal override Symbol? ContainingMemberOrLambda => _factory.CurrentFunction;
|
|
|
|
internal SyntheticBinderImpl(SyntheticBoundNodeFactory factory)
|
|
: base(factory.Compilation, null)
|
|
{
|
|
_factory = factory;
|
|
}
|
|
|
|
internal override bool IsAccessibleHelper(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo, ConsList<TypeSymbol> basesBeingResolved)
|
|
{
|
|
return AccessCheck.IsSymbolAccessible(symbol, _factory.CurrentType, accessThroughType, out failedThroughTypeCheck, ref useSiteInfo, basesBeingResolved);
|
|
}
|
|
}
|
|
|
|
internal readonly struct SyntheticSwitchSection(ImmutableArray<int> values, ImmutableArray<BoundStatement> statements)
|
|
{
|
|
public readonly ImmutableArray<int> Values = values;
|
|
|
|
public readonly ImmutableArray<BoundStatement> Statements = statements;
|
|
}
|
|
|
|
private NamedTypeSymbol? _currentType;
|
|
|
|
private MethodSymbol? _currentFunction;
|
|
|
|
private MethodSymbol? _topLevelMethod;
|
|
|
|
private Binder? _binder;
|
|
|
|
public CSharpCompilation Compilation => CompilationState.Compilation;
|
|
|
|
public SyntaxNode Syntax { get; set; }
|
|
|
|
public PEModuleBuilder? ModuleBuilderOpt => CompilationState.ModuleBuilderOpt;
|
|
|
|
public BindingDiagnosticBag Diagnostics { get; }
|
|
|
|
public InstrumentationState? InstrumentationState { get; }
|
|
|
|
public TypeCompilationState CompilationState { get; }
|
|
|
|
public NamedTypeSymbol? CurrentType
|
|
{
|
|
get
|
|
{
|
|
return _currentType;
|
|
}
|
|
set
|
|
{
|
|
_currentType = value;
|
|
}
|
|
}
|
|
|
|
public MethodSymbol? CurrentFunction
|
|
{
|
|
get
|
|
{
|
|
return _currentFunction;
|
|
}
|
|
set
|
|
{
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001a: Invalid comparison between Unknown and I4
|
|
_currentFunction = value;
|
|
if ((object)value != null && (int)value.MethodKind != 0 && (int)value.MethodKind != 17)
|
|
{
|
|
_topLevelMethod = value;
|
|
_currentType = value.ContainingType;
|
|
}
|
|
}
|
|
}
|
|
|
|
public MethodSymbol? TopLevelMethod
|
|
{
|
|
get
|
|
{
|
|
return _topLevelMethod;
|
|
}
|
|
private set
|
|
{
|
|
_topLevelMethod = value;
|
|
}
|
|
}
|
|
|
|
internal BoundExpression MakeInvocationExpression(BinderFlags flags, SyntaxNode node, BoundExpression receiver, string methodName, ImmutableArray<BoundExpression> args, BindingDiagnosticBag diagnostics, ImmutableArray<TypeSymbol> typeArgs = default(ImmutableArray<TypeSymbol>), bool allowUnexpandedForm = true)
|
|
{
|
|
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
|
|
if (_binder == null || _binder.Flags != flags)
|
|
{
|
|
_binder = new SyntheticBinderImpl(this).WithFlags(flags);
|
|
}
|
|
Binder? binder = _binder;
|
|
ImmutableArray<TypeWithAnnotations> typeArgs2 = (typeArgs.IsDefault ? default(ImmutableArray<TypeWithAnnotations>) : ImmutableArrayExtensions.SelectAsArray<TypeSymbol, TypeWithAnnotations>(typeArgs, (Func<TypeSymbol, TypeWithAnnotations>)((TypeSymbol t) => TypeWithAnnotations.Create(t))));
|
|
bool allowUnexpandedForm2 = allowUnexpandedForm;
|
|
return binder.MakeInvocationExpression(node, receiver, methodName, args, diagnostics, default(SeparatedSyntaxList<TypeSyntax>), typeArgs2, default(ImmutableArray<(string, Location)?>), null, allowFieldsAndProperties: false, allowUnexpandedForm2);
|
|
}
|
|
|
|
public SyntheticBoundNodeFactory(MethodSymbol topLevelMethod, SyntaxNode node, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, InstrumentationState? instrumentationState = null)
|
|
: this(topLevelMethod, topLevelMethod.ContainingType, node, compilationState, diagnostics, instrumentationState)
|
|
{
|
|
}
|
|
|
|
public SyntheticBoundNodeFactory(MethodSymbol? topLevelMethodOpt, NamedTypeSymbol? currentClassOpt, SyntaxNode node, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, InstrumentationState? instrumentationState = null)
|
|
{
|
|
CompilationState = compilationState;
|
|
CurrentType = currentClassOpt;
|
|
TopLevelMethod = topLevelMethodOpt;
|
|
CurrentFunction = topLevelMethodOpt;
|
|
Syntax = node;
|
|
Diagnostics = diagnostics;
|
|
InstrumentationState = instrumentationState;
|
|
}
|
|
|
|
[Conditional("DEBUG")]
|
|
private void CheckCurrentType()
|
|
{
|
|
_ = CurrentType;
|
|
}
|
|
|
|
public void AddNestedType(NamedTypeSymbol nestedType)
|
|
{
|
|
((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)ModuleBuilderOpt).AddSynthesizedDefinition(CurrentType, (INestedTypeDefinition)(object)nestedType.GetCciAdapter());
|
|
}
|
|
|
|
public void OpenNestedType(NamedTypeSymbol nestedType)
|
|
{
|
|
AddNestedType(nestedType);
|
|
CurrentFunction = null;
|
|
TopLevelMethod = null;
|
|
CurrentType = nestedType;
|
|
}
|
|
|
|
public BoundHoistedFieldAccess HoistedField(FieldSymbol field)
|
|
{
|
|
return new BoundHoistedFieldAccess(Syntax, field, field.Type);
|
|
}
|
|
|
|
public StateMachineFieldSymbol StateMachineField(TypeWithAnnotations type, string name, bool isPublic = false, bool isThis = false)
|
|
{
|
|
StateMachineFieldSymbol stateMachineFieldSymbol = new StateMachineFieldSymbol(CurrentType, type, name, isPublic, isThis);
|
|
AddField(CurrentType, stateMachineFieldSymbol);
|
|
return stateMachineFieldSymbol;
|
|
}
|
|
|
|
public StateMachineFieldSymbol StateMachineField(TypeSymbol type, string name, bool isPublic = false, bool isThis = false)
|
|
{
|
|
StateMachineFieldSymbol stateMachineFieldSymbol = new StateMachineFieldSymbol(CurrentType, TypeWithAnnotations.Create(type), name, isPublic, isThis);
|
|
AddField(CurrentType, stateMachineFieldSymbol);
|
|
return stateMachineFieldSymbol;
|
|
}
|
|
|
|
public StateMachineFieldSymbol StateMachineField(TypeSymbol type, string name, SynthesizedLocalKind synthesizedKind, int slotIndex)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
StateMachineFieldSymbol stateMachineFieldSymbol = new StateMachineFieldSymbol(CurrentType, type, name, synthesizedKind, slotIndex, isPublic: false);
|
|
AddField(CurrentType, stateMachineFieldSymbol);
|
|
return stateMachineFieldSymbol;
|
|
}
|
|
|
|
public StateMachineFieldSymbol StateMachineField(TypeSymbol type, string name, LocalSlotDebugInfo slotDebugInfo, int slotIndex)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
StateMachineFieldSymbol stateMachineFieldSymbol = new StateMachineFieldSymbol(CurrentType, type, name, slotDebugInfo, slotIndex, isPublic: false);
|
|
AddField(CurrentType, stateMachineFieldSymbol);
|
|
return stateMachineFieldSymbol;
|
|
}
|
|
|
|
public void AddField(NamedTypeSymbol containingType, FieldSymbol field)
|
|
{
|
|
((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)ModuleBuilderOpt).AddSynthesizedDefinition(containingType, (IFieldDefinition)(object)field.GetCciAdapter());
|
|
}
|
|
|
|
public GeneratedLabelSymbol GenerateLabel(string prefix)
|
|
{
|
|
return new GeneratedLabelSymbol(prefix);
|
|
}
|
|
|
|
public BoundThisReference This()
|
|
{
|
|
return new BoundThisReference(Syntax, CurrentFunction.ThisParameter.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression This(LocalSymbol thisTempOpt)
|
|
{
|
|
if (!(thisTempOpt != null))
|
|
{
|
|
return This();
|
|
}
|
|
return Local(thisTempOpt);
|
|
}
|
|
|
|
public BoundBaseReference Base(NamedTypeSymbol baseType)
|
|
{
|
|
return new BoundBaseReference(Syntax, baseType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundBadExpression BadExpression(TypeSymbol type)
|
|
{
|
|
return new BoundBadExpression(Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray<BoundExpression>.Empty, type, hasErrors: true);
|
|
}
|
|
|
|
public BoundParameter Parameter(ParameterSymbol p)
|
|
{
|
|
return new BoundParameter(Syntax, p, p.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundFieldAccess Field(BoundExpression? receiver, FieldSymbol f)
|
|
{
|
|
return new BoundFieldAccess(Syntax, receiver, f, null, LookupResultKind.Viable, f.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundFieldAccess InstanceField(FieldSymbol f)
|
|
{
|
|
return Field(This(), f);
|
|
}
|
|
|
|
public BoundExpression Property(WellKnownMember member)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
return Property(null, member);
|
|
}
|
|
|
|
public BoundExpression Property(BoundExpression? receiverOpt, WellKnownMember member)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
PropertySymbol propertySymbol = (PropertySymbol)WellKnownMember(member);
|
|
Binder.ReportUseSite(propertySymbol, Diagnostics, Syntax);
|
|
return Property(receiverOpt, propertySymbol);
|
|
}
|
|
|
|
public BoundExpression Property(BoundExpression? receiverOpt, PropertySymbol property)
|
|
{
|
|
MethodSymbol ownOrInheritedGetMethod = property.GetOwnOrInheritedGetMethod();
|
|
return Call(receiverOpt, ownOrInheritedGetMethod);
|
|
}
|
|
|
|
public BoundExpression Indexer(BoundExpression? receiverOpt, PropertySymbol property, BoundExpression arg0)
|
|
{
|
|
MethodSymbol ownOrInheritedGetMethod = property.GetOwnOrInheritedGetMethod();
|
|
return Call(receiverOpt, ownOrInheritedGetMethod, arg0);
|
|
}
|
|
|
|
public NamedTypeSymbol SpecialType(SpecialType st)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
NamedTypeSymbol specialType = Compilation.GetSpecialType(st);
|
|
Binder.ReportUseSite(specialType, Diagnostics, Syntax);
|
|
return specialType;
|
|
}
|
|
|
|
public ArrayTypeSymbol WellKnownArrayType(WellKnownType elementType)
|
|
{
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
return Compilation.CreateArrayTypeSymbol(WellKnownType(elementType));
|
|
}
|
|
|
|
public NamedTypeSymbol WellKnownType(WellKnownType wt)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
NamedTypeSymbol wellKnownType = Compilation.GetWellKnownType(wt);
|
|
Binder.ReportUseSite(wellKnownType, Diagnostics, Syntax);
|
|
return wellKnownType;
|
|
}
|
|
|
|
public Symbol? WellKnownMember(WellKnownMember wm, bool isOptional)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
|
|
Symbol wellKnownTypeMember = Binder.GetWellKnownTypeMember(Compilation, wm, Diagnostics, null, Syntax, isOptional: true);
|
|
if ((object)wellKnownTypeMember == null && !isOptional)
|
|
{
|
|
MemberDescriptor descriptor = WellKnownMembers.GetDescriptor(wm);
|
|
throw new MissingPredefinedMember((Diagnostic)(object)new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, ((MemberDescriptor)(ref descriptor)).DeclaringTypeMetadataName, descriptor.Name), Syntax.Location));
|
|
}
|
|
return wellKnownTypeMember;
|
|
}
|
|
|
|
public Symbol WellKnownMember(WellKnownMember wm)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return WellKnownMember(wm, isOptional: false);
|
|
}
|
|
|
|
public MethodSymbol? WellKnownMethod(WellKnownMember wm, bool isOptional)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return (MethodSymbol)WellKnownMember(wm, isOptional);
|
|
}
|
|
|
|
public MethodSymbol WellKnownMethod(WellKnownMember wm)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return (MethodSymbol)WellKnownMember(wm, isOptional: false);
|
|
}
|
|
|
|
public Symbol SpecialMember(SpecialMember sm)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
Symbol specialTypeMember = Compilation.GetSpecialTypeMember(sm);
|
|
if ((object)specialTypeMember == null)
|
|
{
|
|
MemberDescriptor descriptor = SpecialMembers.GetDescriptor(sm);
|
|
throw new MissingPredefinedMember((Diagnostic)(object)new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, ((MemberDescriptor)(ref descriptor)).DeclaringTypeMetadataName, descriptor.Name), Syntax.Location));
|
|
}
|
|
Binder.ReportUseSite(specialTypeMember, Diagnostics, Syntax);
|
|
return specialTypeMember;
|
|
}
|
|
|
|
public MethodSymbol SpecialMethod(SpecialMember sm)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return (MethodSymbol)SpecialMember(sm);
|
|
}
|
|
|
|
public PropertySymbol SpecialProperty(SpecialMember sm)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return (PropertySymbol)SpecialMember(sm);
|
|
}
|
|
|
|
public BoundExpressionStatement Assignment(BoundExpression left, BoundExpression right, bool isRef = false)
|
|
{
|
|
return ExpressionStatement(AssignmentExpression(left, right, isRef));
|
|
}
|
|
|
|
public BoundExpressionStatement ExpressionStatement(BoundExpression expr)
|
|
{
|
|
return new BoundExpressionStatement(Syntax, expr)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression AssignmentExpression(BoundExpression left, BoundExpression right, bool isRef = false)
|
|
{
|
|
return AssignmentExpression(Syntax, left, right, left.Type, isRef, hasErrors: false, wasCompilerGenerated: true);
|
|
}
|
|
|
|
public BoundExpression AssignmentExpression(SyntaxNode syntax, BoundExpression left, BoundExpression right, TypeSymbol type, bool isRef = false, bool hasErrors = false, bool wasCompilerGenerated = false)
|
|
{
|
|
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
|
BoundAssignmentOperator boundAssignmentOperator = new BoundAssignmentOperator(syntax, left, right, isRef, type, hasErrors)
|
|
{
|
|
WasCompilerGenerated = wasCompilerGenerated
|
|
};
|
|
InstrumentationState? instrumentationState = InstrumentationState;
|
|
bool flag = instrumentationState != null && !instrumentationState.IsSuppressed;
|
|
bool flag2;
|
|
if (flag)
|
|
{
|
|
if (left is BoundLocal boundLocal)
|
|
{
|
|
LocalSymbol localSymbol = boundLocal.LocalSymbol;
|
|
if ((object)localSymbol != null && (int)localSymbol.SynthesizedKind == 0)
|
|
{
|
|
goto IL_0056;
|
|
}
|
|
}
|
|
else if (left is BoundParameter)
|
|
{
|
|
goto IL_0056;
|
|
}
|
|
flag2 = false;
|
|
goto IL_005e;
|
|
}
|
|
goto IL_0061;
|
|
IL_005e:
|
|
flag = flag2;
|
|
goto IL_0061;
|
|
IL_0056:
|
|
flag2 = true;
|
|
goto IL_005e;
|
|
IL_0061:
|
|
if (!flag)
|
|
{
|
|
return boundAssignmentOperator;
|
|
}
|
|
return InstrumentationState.Instrumenter.InstrumentUserDefinedLocalAssignment(boundAssignmentOperator);
|
|
}
|
|
|
|
public BoundBlock Block()
|
|
{
|
|
return Block(ImmutableArray<BoundStatement>.Empty);
|
|
}
|
|
|
|
public BoundBlock Block(ImmutableArray<BoundStatement> statements)
|
|
{
|
|
return Block(ImmutableArray<LocalSymbol>.Empty, statements);
|
|
}
|
|
|
|
public BoundBlock Block(params BoundStatement[] statements)
|
|
{
|
|
return Block(ImmutableArray.Create(statements));
|
|
}
|
|
|
|
public BoundBlock Block(ImmutableArray<LocalSymbol> locals, params BoundStatement[] statements)
|
|
{
|
|
return Block(locals, ImmutableArray.Create(statements));
|
|
}
|
|
|
|
public BoundBlock Block(ImmutableArray<LocalSymbol> locals, ImmutableArray<BoundStatement> statements)
|
|
{
|
|
return new BoundBlock(Syntax, locals, statements)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundBlock Block(ImmutableArray<LocalSymbol> locals, ImmutableArray<LocalFunctionSymbol> localFunctions, params BoundStatement[] statements)
|
|
{
|
|
return Block(locals, localFunctions, ImmutableArray.Create(statements));
|
|
}
|
|
|
|
public BoundBlock Block(ImmutableArray<LocalSymbol> locals, ImmutableArray<LocalFunctionSymbol> localFunctions, ImmutableArray<BoundStatement> statements)
|
|
{
|
|
return new BoundBlock(Syntax, locals, localFunctions, hasUnsafeModifier: false, null, statements)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExtractedFinallyBlock ExtractedFinallyBlock(BoundBlock finallyBlock)
|
|
{
|
|
return new BoundExtractedFinallyBlock(Syntax, finallyBlock)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundStatementList StatementList()
|
|
{
|
|
return StatementList(ImmutableArray<BoundStatement>.Empty);
|
|
}
|
|
|
|
public BoundStatementList StatementList(ImmutableArray<BoundStatement> statements)
|
|
{
|
|
return new BoundStatementList(Syntax, statements)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundStatementList StatementList(BoundStatement first, BoundStatement second)
|
|
{
|
|
return new BoundStatementList(Syntax, ImmutableArray.Create(first, second))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundReturnStatement Return(BoundExpression? expression = null)
|
|
{
|
|
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
if (expression != null)
|
|
{
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
|
|
Conversion conversion = Compilation.Conversions.ClassifyConversionFromType(expression.Type, CurrentFunction.ReturnType, isChecked: false, ref useSiteInfo);
|
|
if (conversion.Kind != ConversionKind.Identity)
|
|
{
|
|
expression = BoundConversion.Synthesized(Syntax, expression, conversion, @checked: false, explicitCastInCode: false, null, null, CurrentFunction.ReturnType);
|
|
}
|
|
}
|
|
return new BoundReturnStatement(Syntax, CurrentFunction.RefKind, expression, @checked: false)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public void CloseMethod(BoundStatement body)
|
|
{
|
|
if (body.Kind != BoundKind.Block)
|
|
{
|
|
body = Block(body);
|
|
}
|
|
CompilationState.AddSynthesizedMethod(CurrentFunction, body);
|
|
CurrentFunction = null;
|
|
}
|
|
|
|
public LocalSymbol SynthesizedLocal(TypeSymbol type, SyntaxNode? syntax = null, bool isPinned = false, bool isKnownToReferToTempIfReferenceType = false, RefKind refKind = (RefKind)0, SynthesizedLocalKind kind = (SynthesizedLocalKind)(-2))
|
|
{
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
|
|
return new SynthesizedLocal(CurrentFunction, TypeWithAnnotations.Create(type), kind, syntax, isPinned, isKnownToReferToTempIfReferenceType, refKind);
|
|
}
|
|
|
|
public LocalSymbol InterpolatedStringHandlerLocal(TypeSymbol type, SyntaxNode syntax)
|
|
{
|
|
return new SynthesizedLocal(CurrentFunction, TypeWithAnnotations.Create(type), (SynthesizedLocalKind)(-2), syntax, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0);
|
|
}
|
|
|
|
public ParameterSymbol SynthesizedParameter(TypeSymbol type, string name, MethodSymbol? container = null, int ordinal = 0)
|
|
{
|
|
return SynthesizedParameterSymbol.Create(container, TypeWithAnnotations.Create(type), ordinal, (RefKind)0, name, (ScopedKind)0);
|
|
}
|
|
|
|
public BoundBinaryOperator Binary(BinaryOperatorKind kind, TypeSymbol type, BoundExpression left, BoundExpression right)
|
|
{
|
|
return new BoundBinaryOperator(Syntax, kind, null, null, null, LookupResultKind.Viable, left, right, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundAsOperator As(BoundExpression operand, TypeSymbol type)
|
|
{
|
|
return new BoundAsOperator(Syntax, operand, Type(type), null, null, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundIsOperator Is(BoundExpression operand, TypeSymbol type)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
|
|
Conversion conversion = Compilation.Conversions.ClassifyBuiltInConversion(operand.Type, type, isChecked: false, ref useSiteInfo);
|
|
return new BoundIsOperator(Syntax, operand, Type(type), conversion.Kind, SpecialType((SpecialType)7))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundBinaryOperator LogicalAnd(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.LogicalBoolAnd, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator LogicalOr(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.LogicalBoolOr, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntEqual(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntEqual, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator ObjectEqual(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.ObjectEqual, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator ObjectNotEqual(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.ObjectNotEqual, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntNotEqual(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntNotEqual, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntLessThan(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntLessThan, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntGreaterThanOrEqual(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntGreaterThanOrEqual, SpecialType((SpecialType)7), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntSubtract(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntSubtraction, SpecialType((SpecialType)13), left, right);
|
|
}
|
|
|
|
public BoundBinaryOperator IntMultiply(BoundExpression left, BoundExpression right)
|
|
{
|
|
return Binary(BinaryOperatorKind.IntMultiplication, SpecialType((SpecialType)13), left, right);
|
|
}
|
|
|
|
public BoundLiteral Literal(byte value)
|
|
{
|
|
return new BoundLiteral(Syntax, ConstantValue.Create(value), SpecialType((SpecialType)10))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral Literal(int value)
|
|
{
|
|
return new BoundLiteral(Syntax, ConstantValue.Create(value), SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral Literal(StateMachineState value)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Expected I4, but got Unknown
|
|
return Literal((int)value);
|
|
}
|
|
|
|
public BoundLiteral Literal(uint value)
|
|
{
|
|
return new BoundLiteral(Syntax, ConstantValue.Create(value), SpecialType((SpecialType)14))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral Literal(ConstantValue value, TypeSymbol type)
|
|
{
|
|
return new BoundLiteral(Syntax, value, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundObjectCreationExpression New(NamedTypeSymbol type, params BoundExpression[] args)
|
|
{
|
|
MethodSymbol ctor = type.InstanceConstructors.Single((MethodSymbol c) => c.ParameterCount == args.Length);
|
|
return New(ctor, args);
|
|
}
|
|
|
|
public BoundObjectCreationExpression New(MethodSymbol ctor, params BoundExpression[] args)
|
|
{
|
|
return New(ctor, ((IEnumerable<BoundExpression>)args).ToImmutableArray());
|
|
}
|
|
|
|
public BoundObjectCreationExpression New(NamedTypeSymbol type, ImmutableArray<BoundExpression> args)
|
|
{
|
|
MethodSymbol ctor = type.InstanceConstructors.Single((MethodSymbol c) => c.ParameterCount == args.Length);
|
|
return New(ctor, args);
|
|
}
|
|
|
|
public BoundObjectCreationExpression New(MethodSymbol ctor, ImmutableArray<BoundExpression> args)
|
|
{
|
|
return new BoundObjectCreationExpression(Syntax, ctor, args)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundObjectCreationExpression New(WellKnownMember wm, ImmutableArray<BoundExpression> args)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
MethodSymbol constructor = WellKnownMethod(wm);
|
|
return new BoundObjectCreationExpression(Syntax, constructor, args)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression MakeIsNotANumberTest(BoundExpression input)
|
|
{
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Invalid comparison between Unknown and I4
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0019: Invalid comparison between Unknown and I4
|
|
TypeSymbol type = input.Type;
|
|
if ((object)type != null)
|
|
{
|
|
SpecialType specialType = type.SpecialType;
|
|
if ((int)specialType == 18)
|
|
{
|
|
return StaticCall((SpecialMember)16, input);
|
|
}
|
|
if ((int)specialType == 19)
|
|
{
|
|
return StaticCall((SpecialMember)15, input);
|
|
}
|
|
}
|
|
throw ExceptionUtilities.UnexpectedValue((object)input.Type);
|
|
}
|
|
|
|
public BoundExpression InstanceCall(BoundExpression receiver, string name, BoundExpression arg)
|
|
{
|
|
return MakeInvocationExpression(BinderFlags.None, Syntax, receiver, name, ImmutableArray.Create(arg), Diagnostics);
|
|
}
|
|
|
|
public BoundExpression InstanceCall(BoundExpression receiver, string name)
|
|
{
|
|
return MakeInvocationExpression(BinderFlags.None, Syntax, receiver, name, ImmutableArray<BoundExpression>.Empty, Diagnostics);
|
|
}
|
|
|
|
public BoundExpression StaticCall(TypeSymbol receiver, string name, params BoundExpression[] args)
|
|
{
|
|
return MakeInvocationExpression(BinderFlags.None, Syntax, Type(receiver), name, ((IEnumerable<BoundExpression>)args).ToImmutableArray(), Diagnostics);
|
|
}
|
|
|
|
public BoundExpression StaticCall(TypeSymbol receiver, string name, ImmutableArray<BoundExpression> args, bool allowUnexpandedForm)
|
|
{
|
|
SyntaxNode syntax = Syntax;
|
|
BoundTypeExpression receiver2 = Type(receiver);
|
|
BindingDiagnosticBag diagnostics = Diagnostics;
|
|
bool allowUnexpandedForm2 = allowUnexpandedForm;
|
|
return MakeInvocationExpression(BinderFlags.None, syntax, receiver2, name, args, diagnostics, default(ImmutableArray<TypeSymbol>), allowUnexpandedForm2);
|
|
}
|
|
|
|
public BoundExpression StaticCall(BinderFlags flags, TypeSymbol receiver, string name, ImmutableArray<TypeSymbol> typeArgs, params BoundExpression[] args)
|
|
{
|
|
return MakeInvocationExpression(flags, Syntax, Type(receiver), name, ((IEnumerable<BoundExpression>)args).ToImmutableArray(), Diagnostics, typeArgs);
|
|
}
|
|
|
|
public BoundExpression StaticCall(TypeSymbol receiver, MethodSymbol method, params BoundExpression[] args)
|
|
{
|
|
if ((object)method == null)
|
|
{
|
|
return new BoundBadExpression(Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArrayExtensions.AsImmutable<BoundExpression>(args), receiver);
|
|
}
|
|
return Call(null, method, args);
|
|
}
|
|
|
|
public BoundExpression StaticCall(MethodSymbol method, ImmutableArray<BoundExpression> args)
|
|
{
|
|
return Call(null, method, args);
|
|
}
|
|
|
|
public BoundExpression StaticCall(WellKnownMember method, params BoundExpression[] args)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
MethodSymbol methodSymbol = WellKnownMethod(method);
|
|
Binder.ReportUseSite(methodSymbol, Diagnostics, Syntax);
|
|
return Call(null, methodSymbol, args);
|
|
}
|
|
|
|
public BoundExpression StaticCall(SpecialMember method, params BoundExpression[] args)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
MethodSymbol methodSymbol = SpecialMethod(method);
|
|
Binder.ReportUseSite(methodSymbol, Diagnostics, Syntax);
|
|
return Call(null, methodSymbol, args);
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method)
|
|
{
|
|
return Call(receiver, method, ImmutableArray<BoundExpression>.Empty);
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method, BoundExpression arg0, bool useStrictArgumentRefKinds = false)
|
|
{
|
|
return Call(receiver, method, ImmutableArray.Create(arg0), useStrictArgumentRefKinds);
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method, BoundExpression arg0, BoundExpression arg1, bool useStrictArgumentRefKinds = false)
|
|
{
|
|
return Call(receiver, method, ImmutableArray.Create(arg0, arg1), useStrictArgumentRefKinds);
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method, params BoundExpression[] args)
|
|
{
|
|
return Call(receiver, method, ImmutableArray.Create(args));
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, WellKnownMember method, BoundExpression arg0)
|
|
{
|
|
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
|
|
return Call(receiver, WellKnownMethod(method), ImmutableArray.Create(arg0));
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method, ImmutableArray<BoundExpression> args, bool useStrictArgumentRefKinds = false)
|
|
{
|
|
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
|
|
return new BoundCall(Syntax, receiver, (ThreeState)0, method, args, default(ImmutableArray<string>), getArgumentRefKinds(method, useStrictArgumentRefKinds), isDelegateCall: false, expanded: false, invokedAsExtensionMethod: false, default(ImmutableArray<int>), default(BitVector), LookupResultKind.Viable, method.ReturnType, method.OriginalDefinition is ErrorMethodSymbol)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
static ImmutableArray<RefKind> getArgumentRefKinds(MethodSymbol methodSymbol, bool flag)
|
|
{
|
|
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0052: Invalid comparison between Unknown and I4
|
|
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0057: Invalid comparison between Unknown and I4
|
|
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
|
|
ImmutableArray<RefKind> parameterRefKinds = methodSymbol.ParameterRefKinds;
|
|
if (!parameterRefKinds.IsDefaultOrEmpty && (parameterRefKinds.Contains((RefKind)4) || (flag && parameterRefKinds.Contains((RefKind)3))))
|
|
{
|
|
ArrayBuilder<RefKind> instance = ArrayBuilder<RefKind>.GetInstance(parameterRefKinds.Length);
|
|
ArrayBuilder<RefKind> val;
|
|
RefKind val3;
|
|
for (ImmutableArray<RefKind>.Enumerator enumerator = parameterRefKinds.GetEnumerator(); enumerator.MoveNext(); val.Add(val3))
|
|
{
|
|
RefKind current = enumerator.Current;
|
|
val = instance;
|
|
RefKind val2 = current;
|
|
int num;
|
|
if ((int)val2 != 3)
|
|
{
|
|
if ((int)val2 != 4)
|
|
{
|
|
goto IL_0079;
|
|
}
|
|
num = 1;
|
|
}
|
|
else
|
|
{
|
|
num = 0;
|
|
}
|
|
if (!flag)
|
|
{
|
|
if (num == 0)
|
|
{
|
|
goto IL_0079;
|
|
}
|
|
if (num == 1)
|
|
{
|
|
val3 = (RefKind)3;
|
|
continue;
|
|
}
|
|
}
|
|
val3 = (RefKind)5;
|
|
continue;
|
|
IL_0079:
|
|
val3 = current;
|
|
}
|
|
return instance.ToImmutableAndFree();
|
|
}
|
|
return parameterRefKinds;
|
|
}
|
|
}
|
|
|
|
public BoundCall Call(BoundExpression? receiver, MethodSymbol method, ImmutableArray<RefKind> refKinds, ImmutableArray<BoundExpression> args)
|
|
{
|
|
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
return new BoundCall(Syntax, receiver, (ThreeState)0, method, args, default(ImmutableArray<string>), refKinds, isDelegateCall: false, expanded: false, invokedAsExtensionMethod: false, ImmutableArray<int>.Empty, default(BitVector), LookupResultKind.Viable, method.ReturnType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Conditional(BoundExpression condition, BoundExpression consequence, BoundExpression alternative, TypeSymbol type, bool isRef = false)
|
|
{
|
|
return new BoundConditionalOperator(Syntax, isRef, condition, consequence, alternative, null, type, wasTargetTyped: false, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundComplexConditionalReceiver ComplexConditionalReceiver(BoundExpression valueTypeReceiver, BoundExpression referenceTypeReceiver)
|
|
{
|
|
return new BoundComplexConditionalReceiver(Syntax, valueTypeReceiver, referenceTypeReceiver, valueTypeReceiver.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Coalesce(BoundExpression left, BoundExpression right)
|
|
{
|
|
return new BoundNullCoalescingOperator(Syntax, left, right, null, null, BoundNullCoalescingOperatorResultKind.LeftType, @checked: false, left.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundStatement If(BoundExpression condition, BoundStatement thenClause, BoundStatement? elseClauseOpt = null)
|
|
{
|
|
return If(condition, ImmutableArray<LocalSymbol>.Empty, thenClause, elseClauseOpt);
|
|
}
|
|
|
|
public BoundStatement ConditionalGoto(BoundExpression condition, LabelSymbol label, bool jumpIfTrue)
|
|
{
|
|
return new BoundConditionalGoto(Syntax, condition, jumpIfTrue, label)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundStatement If(BoundExpression condition, ImmutableArray<LocalSymbol> locals, BoundStatement thenClause, BoundStatement? elseClauseOpt = null)
|
|
{
|
|
ArrayBuilder<BoundStatement> instance = ArrayBuilder<BoundStatement>.GetInstance();
|
|
GeneratedLabelSymbol label = new GeneratedLabelSymbol("afterif");
|
|
if (elseClauseOpt != null)
|
|
{
|
|
GeneratedLabelSymbol label2 = new GeneratedLabelSymbol("alternative");
|
|
instance.Add(ConditionalGoto(condition, label2, jumpIfTrue: false));
|
|
instance.Add(thenClause);
|
|
instance.Add((BoundStatement)Goto(label));
|
|
if (!locals.IsDefaultOrEmpty)
|
|
{
|
|
BoundBlock boundBlock = Block(locals, instance.ToImmutable());
|
|
instance.Clear();
|
|
instance.Add((BoundStatement)boundBlock);
|
|
}
|
|
instance.Add((BoundStatement)Label(label2));
|
|
instance.Add(elseClauseOpt);
|
|
}
|
|
else
|
|
{
|
|
instance.Add(ConditionalGoto(condition, label, jumpIfTrue: false));
|
|
instance.Add(thenClause);
|
|
if (!locals.IsDefaultOrEmpty)
|
|
{
|
|
BoundBlock boundBlock2 = Block(locals, instance.ToImmutable());
|
|
instance.Clear();
|
|
instance.Add((BoundStatement)boundBlock2);
|
|
}
|
|
}
|
|
instance.Add((BoundStatement)Label(label));
|
|
return Block(instance.ToImmutableAndFree());
|
|
}
|
|
|
|
public BoundThrowStatement Throw(BoundExpression e)
|
|
{
|
|
return new BoundThrowStatement(Syntax, e)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLocal Local(LocalSymbol local)
|
|
{
|
|
return new BoundLocal(Syntax, local, null, local.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression MakeSequence(LocalSymbol temp, params BoundExpression[] parts)
|
|
{
|
|
return MakeSequence(ImmutableArray.Create(temp), parts);
|
|
}
|
|
|
|
public BoundExpression MakeSequence(params BoundExpression[] parts)
|
|
{
|
|
return MakeSequence(ImmutableArray<LocalSymbol>.Empty, parts);
|
|
}
|
|
|
|
public BoundExpression MakeSequence(ImmutableArray<LocalSymbol> locals, params BoundExpression[] parts)
|
|
{
|
|
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
|
|
for (int i = 0; i < parts.Length - 1; i++)
|
|
{
|
|
if (LocalRewriter.ReadIsSideeffecting(parts[i]))
|
|
{
|
|
instance.Add(parts[i]);
|
|
}
|
|
}
|
|
BoundExpression result = parts[^1];
|
|
if (locals.IsDefaultOrEmpty && instance.Count == 0)
|
|
{
|
|
instance.Free();
|
|
return result;
|
|
}
|
|
return Sequence(locals, instance.ToImmutableAndFree(), result);
|
|
}
|
|
|
|
public BoundSequence Sequence(BoundExpression[] sideEffects, BoundExpression result, TypeSymbol? type = null)
|
|
{
|
|
TypeSymbol type2 = type ?? result.Type;
|
|
return new BoundSequence(Syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArrayExtensions.AsImmutableOrNull<BoundExpression>(sideEffects), result, type2)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Sequence(ImmutableArray<LocalSymbol> locals, ImmutableArray<BoundExpression> sideEffects, BoundExpression result)
|
|
{
|
|
if (!locals.IsDefaultOrEmpty || !sideEffects.IsDefaultOrEmpty)
|
|
{
|
|
return new BoundSequence(Syntax, locals, sideEffects, result, result.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public BoundSpillSequence SpillSequence(ImmutableArray<LocalSymbol> locals, ImmutableArray<BoundStatement> sideEffects, BoundExpression result)
|
|
{
|
|
return new BoundSpillSequence(Syntax, locals, sideEffects, result, result.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public SyntheticSwitchSection SwitchSection(int value, params BoundStatement[] statements)
|
|
{
|
|
return SwitchSection(ImmutableArray.Create(value), statements);
|
|
}
|
|
|
|
public SyntheticSwitchSection SwitchSection(ImmutableArray<int> values, params BoundStatement[] statements)
|
|
{
|
|
return new SyntheticSwitchSection(values, ImmutableArray.Create(statements));
|
|
}
|
|
|
|
public BoundStatement Switch(BoundExpression ex, ImmutableArray<SyntheticSwitchSection> sections)
|
|
{
|
|
if (sections.Length == 0)
|
|
{
|
|
return ExpressionStatement(ex);
|
|
}
|
|
GeneratedLabelSymbol generatedLabelSymbol = new GeneratedLabelSymbol("break");
|
|
ArrayBuilder<(ConstantValue, LabelSymbol)> instance = ArrayBuilder<(ConstantValue, LabelSymbol)>.GetInstance();
|
|
ArrayBuilder<BoundStatement> instance2 = ArrayBuilder<BoundStatement>.GetInstance();
|
|
instance2.Add((BoundStatement)null);
|
|
ImmutableArray<SyntheticSwitchSection>.Enumerator enumerator = sections.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
SyntheticSwitchSection current = enumerator.Current;
|
|
LabelSymbol labelSymbol = new GeneratedLabelSymbol("case " + current.Values[0]);
|
|
instance2.Add((BoundStatement)Label(labelSymbol));
|
|
instance2.AddRange(current.Statements);
|
|
ImmutableArray<int>.Enumerator enumerator2 = current.Values.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
int current2 = enumerator2.Current;
|
|
instance.Add((ConstantValue.Create(current2), labelSymbol));
|
|
}
|
|
}
|
|
instance2.Add((BoundStatement)Label(generatedLabelSymbol));
|
|
instance2[0] = new BoundSwitchDispatch(Syntax, ex, instance.ToImmutableAndFree(), generatedLabelSymbol, null)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
return Block(instance2.ToImmutableAndFree());
|
|
}
|
|
|
|
[Conditional("DEBUG")]
|
|
private static void CheckSwitchSections(ImmutableArray<SyntheticSwitchSection> sections)
|
|
{
|
|
HashSet<int> hashSet = new HashSet<int>();
|
|
ImmutableArray<SyntheticSwitchSection>.Enumerator enumerator = sections.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
ImmutableArray<int>.Enumerator enumerator2 = enumerator.Current.Values.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
int current = enumerator2.Current;
|
|
hashSet.Add(current);
|
|
}
|
|
}
|
|
}
|
|
|
|
public BoundGotoStatement Goto(LabelSymbol label)
|
|
{
|
|
return new BoundGotoStatement(Syntax, label)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLabelStatement Label(LabelSymbol label)
|
|
{
|
|
return new BoundLabelStatement(Syntax, label)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral Literal(bool value)
|
|
{
|
|
return new BoundLiteral(Syntax, ConstantValue.Create(value), SpecialType((SpecialType)7))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral Literal(string? value)
|
|
{
|
|
ConstantValue stringConst = ConstantValue.Create(value);
|
|
return StringLiteral(stringConst);
|
|
}
|
|
|
|
public BoundLiteral StringLiteral(ConstantValue stringConst)
|
|
{
|
|
return new BoundLiteral(Syntax, stringConst, SpecialType((SpecialType)20))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral StringLiteral(string stringValue)
|
|
{
|
|
return StringLiteral(ConstantValue.Create(stringValue));
|
|
}
|
|
|
|
public BoundLiteral CharLiteral(ConstantValue charConst)
|
|
{
|
|
return new BoundLiteral(Syntax, charConst, SpecialType((SpecialType)8))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundLiteral CharLiteral(char charValue)
|
|
{
|
|
return CharLiteral(ConstantValue.Create(charValue));
|
|
}
|
|
|
|
public BoundArrayLength ArrayLength(BoundExpression array)
|
|
{
|
|
return new BoundArrayLength(Syntax, array, SpecialType((SpecialType)13));
|
|
}
|
|
|
|
public BoundArrayAccess ArrayAccessFirstElement(BoundExpression array)
|
|
{
|
|
ImmutableArray<BoundExpression> indices = ArrayBuilder<BoundExpression>.GetInstance(((ArrayTypeSymbol)array.Type).Rank, (BoundExpression)Literal(0)).ToImmutableAndFree();
|
|
return ArrayAccess(array, indices);
|
|
}
|
|
|
|
public BoundArrayAccess ArrayAccess(BoundExpression array, params BoundExpression[] indices)
|
|
{
|
|
return ArrayAccess(array, ImmutableArrayExtensions.AsImmutableOrNull<BoundExpression>(indices));
|
|
}
|
|
|
|
public BoundArrayAccess ArrayAccess(BoundExpression array, ImmutableArray<BoundExpression> indices)
|
|
{
|
|
return new BoundArrayAccess(Syntax, array, indices, ((ArrayTypeSymbol)array.Type).ElementType);
|
|
}
|
|
|
|
public BoundStatement BaseInitialization()
|
|
{
|
|
NamedTypeSymbol baseTypeNoUseSiteDiagnostics = CurrentFunction.ThisParameter.Type.BaseTypeNoUseSiteDiagnostics;
|
|
MethodSymbol method = baseTypeNoUseSiteDiagnostics.InstanceConstructors.Single((MethodSymbol c) => c.ParameterCount == 0);
|
|
return new BoundExpressionStatement(Syntax, Call(Base(baseTypeNoUseSiteDiagnostics), method))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundStatement SequencePoint(SyntaxNode syntax, BoundStatement statement)
|
|
{
|
|
return new BoundSequencePoint(syntax, statement);
|
|
}
|
|
|
|
public BoundStatement SequencePointWithSpan(CSharpSyntaxNode syntax, TextSpan span, BoundStatement statement)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
return new BoundSequencePointWithSpan((SyntaxNode)(object)syntax, statement, span);
|
|
}
|
|
|
|
public BoundStatement HiddenSequencePoint(BoundStatement? statementOpt = null)
|
|
{
|
|
return BoundSequencePoint.CreateHidden(statementOpt);
|
|
}
|
|
|
|
public BoundStatement ThrowNull()
|
|
{
|
|
return Throw(Null(Binder.GetWellKnownType(Compilation, (WellKnownType)52, Diagnostics, Syntax.Location)));
|
|
}
|
|
|
|
public BoundExpression ThrowExpression(BoundExpression thrown, TypeSymbol type)
|
|
{
|
|
return new BoundThrowExpression(thrown.Syntax, thrown, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Null(TypeSymbol type)
|
|
{
|
|
return Null(type, Syntax);
|
|
}
|
|
|
|
public BoundExpression NullRef(TypeWithAnnotations type)
|
|
{
|
|
return new BoundPointerIndirectionOperator(Syntax, Default(new PointerTypeSymbol(type)), refersToLocation: false, type.Type);
|
|
}
|
|
|
|
public static BoundExpression Null(TypeSymbol type, SyntaxNode syntax)
|
|
{
|
|
BoundExpression boundExpression = new BoundLiteral(syntax, ConstantValue.Null, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
if (!type.IsPointerOrFunctionPointer())
|
|
{
|
|
return boundExpression;
|
|
}
|
|
return BoundConversion.SynthesizedNonUserDefined(syntax, boundExpression, Conversion.NullToPointer, type);
|
|
}
|
|
|
|
public BoundTypeExpression Type(TypeSymbol type)
|
|
{
|
|
return new BoundTypeExpression(Syntax, null, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Typeof(WellKnownType type)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
return Typeof((TypeSymbol)WellKnownType(type));
|
|
}
|
|
|
|
public BoundExpression Typeof(TypeSymbol type)
|
|
{
|
|
return new BoundTypeOfOperator(Syntax, Type(type), WellKnownMethod((WellKnownMember)42), WellKnownType((WellKnownType)61))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression Typeof(TypeWithAnnotations type)
|
|
{
|
|
return Typeof(type.Type);
|
|
}
|
|
|
|
public ImmutableArray<BoundExpression> TypeOfs(ImmutableArray<TypeWithAnnotations> typeArguments)
|
|
{
|
|
return ImmutableArrayExtensions.SelectAsArray<TypeWithAnnotations, BoundExpression>(typeArguments, (Func<TypeWithAnnotations, BoundExpression>)Typeof);
|
|
}
|
|
|
|
public BoundExpression TypeofDynamicOperationContextType()
|
|
{
|
|
return Typeof((TypeSymbol)CompilationState.DynamicOperationContextType);
|
|
}
|
|
|
|
public BoundExpression Sizeof(TypeSymbol type)
|
|
{
|
|
return new BoundSizeOfOperator(Syntax, Type(type), Binder.GetConstantSizeOf(type), SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal BoundExpression ConstructorInfo(MethodSymbol ctor)
|
|
{
|
|
return new BoundMethodInfo(Syntax, ctor, GetMethodFromHandleMethod(ctor.ContainingType), WellKnownType((WellKnownType)65))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression MethodDefIndex(MethodSymbol method)
|
|
{
|
|
return new BoundMethodDefIndex(Syntax, method, SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression LocalId(LocalSymbol symbol)
|
|
{
|
|
return new BoundLocalId(Syntax, symbol, null, SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression ParameterId(ParameterSymbol symbol)
|
|
{
|
|
return new BoundParameterId(Syntax, symbol, null, SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression StateMachineInstanceId()
|
|
{
|
|
return new BoundStateMachineInstanceId(Syntax, SpecialType((SpecialType)16))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression ModuleVersionId()
|
|
{
|
|
return new BoundModuleVersionId(Syntax, WellKnownType((WellKnownType)55))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression ModuleVersionIdString()
|
|
{
|
|
return new BoundModuleVersionIdString(Syntax, SpecialType((SpecialType)20))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression InstrumentationPayloadRoot(int analysisKind, TypeSymbol payloadType)
|
|
{
|
|
return new BoundInstrumentationPayloadRoot(Syntax, analysisKind, payloadType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression MaximumMethodDefIndex()
|
|
{
|
|
return new BoundMaximumMethodDefIndex(Syntax, SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression SourceDocumentIndex(DebugSourceDocument document)
|
|
{
|
|
return new BoundSourceDocumentIndex(Syntax, document, SpecialType((SpecialType)13))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression MethodInfo(MethodSymbol method)
|
|
{
|
|
if (!method.ContainingType.IsValueType || !CodeGenerator.MayUseCallForStructMethod(method))
|
|
{
|
|
method = method.GetConstructedLeastOverriddenMethod(CompilationState.Type, requireSameReturnType: true);
|
|
}
|
|
return new BoundMethodInfo(Syntax, method, GetMethodFromHandleMethod(method.ContainingType), WellKnownType((WellKnownType)64))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression FieldInfo(FieldSymbol field)
|
|
{
|
|
return new BoundFieldInfo(Syntax, field, GetFieldFromHandleMethod(field.ContainingType), WellKnownType((WellKnownType)67))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
private MethodSymbol GetMethodFromHandleMethod(NamedTypeSymbol methodContainer)
|
|
{
|
|
return WellKnownMethod((WellKnownMember)((methodContainer.AllTypeArgumentCount() == 0 && !methodContainer.IsAnonymousType) ? 47 : 48));
|
|
}
|
|
|
|
private MethodSymbol GetFieldFromHandleMethod(NamedTypeSymbol fieldContainer)
|
|
{
|
|
return WellKnownMethod((WellKnownMember)((fieldContainer.AllTypeArgumentCount() == 0) ? 52 : 53));
|
|
}
|
|
|
|
public BoundExpression Convert(TypeSymbol type, BoundExpression arg)
|
|
{
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
if (TypeSymbol.Equals(type, arg.Type, (TypeCompareKind)0))
|
|
{
|
|
return arg;
|
|
}
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
|
|
Conversion conversion = Compilation.Conversions.ClassifyConversionFromExpression(arg, type, isChecked: false, ref useSiteInfo);
|
|
return Convert(type, arg, conversion);
|
|
}
|
|
|
|
public BoundExpression Convert(TypeSymbol type, BoundExpression arg, Conversion conversion, bool isChecked = false)
|
|
{
|
|
if ((object)conversion.Method != null && !TypeSymbol.Equals(conversion.Method.Parameters[0].Type, arg.Type, (TypeCompareKind)0))
|
|
{
|
|
arg = Convert(conversion.Method.Parameters[0].Type, arg);
|
|
}
|
|
if (conversion.Kind == ConversionKind.ImplicitReference && arg.IsLiteralNull())
|
|
{
|
|
return Null(type);
|
|
}
|
|
if (conversion.Kind == ConversionKind.ExplicitNullable && arg.Type.IsNullableType() && arg.Type.GetNullableUnderlyingType().Equals(type, (TypeCompareKind)63))
|
|
{
|
|
return Call(arg, SpecialMethod((SpecialMember)115).AsMember((NamedTypeSymbol)arg.Type));
|
|
}
|
|
return new BoundConversion(Syntax, arg, conversion, isChecked, explicitCastInCode: true, null, null, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
public BoundExpression ArrayOrEmpty(TypeSymbol elementType, BoundExpression[] elements)
|
|
{
|
|
return ArrayOrEmpty(elementType, ImmutableArrayExtensions.AsImmutable<BoundExpression>(elements));
|
|
}
|
|
|
|
public BoundExpression ArrayOrEmpty(TypeSymbol elementType, ImmutableArray<BoundExpression> elements)
|
|
{
|
|
if (elements.Length == 0)
|
|
{
|
|
MethodSymbol methodSymbol = WellKnownMethod((WellKnownMember)4, isOptional: true);
|
|
if ((object)methodSymbol != null)
|
|
{
|
|
methodSymbol = methodSymbol.Construct(ImmutableArray.Create(elementType));
|
|
return Call(null, methodSymbol);
|
|
}
|
|
}
|
|
return Array(elementType, elements);
|
|
}
|
|
|
|
public BoundExpression Array(TypeSymbol elementType, ImmutableArray<BoundExpression> elements)
|
|
{
|
|
return new BoundArrayCreation(Syntax, ImmutableArray.Create((BoundExpression)Literal(elements.Length)), new BoundArrayInitialization(Syntax, isInferred: false, elements)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, Compilation.CreateArrayTypeSymbol(elementType));
|
|
}
|
|
|
|
public BoundExpression Array(TypeSymbol elementType, BoundExpression length)
|
|
{
|
|
return new BoundArrayCreation(Syntax, ImmutableArray.Create(length), null, Compilation.CreateArrayTypeSymbol(elementType))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal BoundExpression Default(TypeSymbol type)
|
|
{
|
|
return Default(type, Syntax);
|
|
}
|
|
|
|
internal static BoundExpression Default(TypeSymbol type, SyntaxNode syntax)
|
|
{
|
|
return new BoundDefaultExpression(syntax, type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal BoundStatement Try(BoundBlock tryBlock, ImmutableArray<BoundCatchBlock> catchBlocks, BoundBlock? finallyBlock = null, LabelSymbol? finallyLabel = null)
|
|
{
|
|
return new BoundTryStatement(Syntax, tryBlock, catchBlocks, finallyBlock, finallyLabel)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal ImmutableArray<BoundCatchBlock> CatchBlocks(params BoundCatchBlock[] catchBlocks)
|
|
{
|
|
return ImmutableArrayExtensions.AsImmutableOrNull<BoundCatchBlock>(catchBlocks);
|
|
}
|
|
|
|
internal BoundCatchBlock Catch(LocalSymbol local, BoundBlock block)
|
|
{
|
|
BoundLocal boundLocal = Local(local);
|
|
return new BoundCatchBlock(Syntax, ImmutableArray.Create(local), boundLocal, boundLocal.Type, null, null, block, isSynthesizedAsyncCatchAll: false);
|
|
}
|
|
|
|
internal BoundCatchBlock Catch(BoundExpression source, BoundBlock block)
|
|
{
|
|
return new BoundCatchBlock(Syntax, ImmutableArray<LocalSymbol>.Empty, source, source.Type, null, null, block, isSynthesizedAsyncCatchAll: false);
|
|
}
|
|
|
|
internal BoundTryStatement Fault(BoundBlock tryBlock, BoundBlock faultBlock)
|
|
{
|
|
return new BoundTryStatement(Syntax, tryBlock, ImmutableArray<BoundCatchBlock>.Empty, faultBlock, null, preferFaultHandler: true);
|
|
}
|
|
|
|
internal BoundExpression NullOrDefault(TypeSymbol typeSymbol)
|
|
{
|
|
return NullOrDefault(typeSymbol, Syntax);
|
|
}
|
|
|
|
internal static BoundExpression NullOrDefault(TypeSymbol typeSymbol, SyntaxNode syntax)
|
|
{
|
|
if (!typeSymbol.IsReferenceType)
|
|
{
|
|
return Default(typeSymbol, syntax);
|
|
}
|
|
return Null(typeSymbol, syntax);
|
|
}
|
|
|
|
internal BoundExpression Not(BoundExpression expression)
|
|
{
|
|
return new BoundUnaryOperator(expression.Syntax, UnaryOperatorKind.BoolLogicalNegation, expression, null, null, null, LookupResultKind.Viable, expression.Type);
|
|
}
|
|
|
|
public BoundLocal StoreToTemp(BoundExpression argument, out BoundAssignmentOperator store, RefKind refKind = (RefKind)0, SynthesizedLocalKind kind = (SynthesizedLocalKind)(-2), bool isKnownToReferToTempIfReferenceType = false, SyntaxNode? syntaxOpt = null)
|
|
{
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Expected I4, but got Unknown
|
|
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a2: Invalid comparison between Unknown and I4
|
|
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
|
MethodSymbol currentFunction = CurrentFunction;
|
|
switch ((int)refKind)
|
|
{
|
|
case 2:
|
|
refKind = (RefKind)1;
|
|
break;
|
|
case 3:
|
|
if (!Binder.HasHome(argument, Binder.AddressKind.ReadOnly, currentFunction, Compilation.IsPeVerifyCompatEnabled, null))
|
|
{
|
|
refKind = (RefKind)0;
|
|
}
|
|
break;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)refKind);
|
|
case 0:
|
|
case 1:
|
|
case 5:
|
|
break;
|
|
}
|
|
SyntaxNode syntax = argument.Syntax;
|
|
TypeSymbol type = argument.Type;
|
|
BoundLocal boundLocal = new BoundLocal(syntax, new SynthesizedLocal(currentFunction, TypeWithAnnotations.Create(type), kind, syntaxOpt ?? (SynthesizedLocalKindExtensions.IsLongLived(kind) ? syntax : null), isPinned: false, isKnownToReferToTempIfReferenceType, refKind), null, type);
|
|
store = new BoundAssignmentOperator(syntax, boundLocal, argument, type, (int)refKind > 0);
|
|
return boundLocal;
|
|
}
|
|
|
|
internal BoundStatement NoOp(NoOpStatementFlavor noOpStatementFlavor)
|
|
{
|
|
return new BoundNoOpStatement(Syntax, noOpStatementFlavor);
|
|
}
|
|
|
|
internal BoundLocal MakeTempForDiscard(BoundDiscardExpression node, ArrayBuilder<LocalSymbol> temps)
|
|
{
|
|
LocalSymbol temp;
|
|
BoundLocal result = MakeTempForDiscard(node, out temp);
|
|
temps.Add(temp);
|
|
return result;
|
|
}
|
|
|
|
internal BoundLocal MakeTempForDiscard(BoundDiscardExpression node, out LocalSymbol temp)
|
|
{
|
|
temp = new SynthesizedLocal(CurrentFunction, TypeWithAnnotations.Create(node.Type), (SynthesizedLocalKind)(-2), null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0);
|
|
return new BoundLocal(node.Syntax, temp, null, node.Type)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal ImmutableArray<BoundExpression> MakeTempsForDiscardArguments(ImmutableArray<BoundExpression> arguments, ArrayBuilder<LocalSymbol> builder)
|
|
{
|
|
if (arguments.Any((BoundExpression a) => a.Kind == BoundKind.DiscardExpression))
|
|
{
|
|
arguments = ImmutableArrayExtensions.SelectAsArray<BoundExpression, (SyntheticBoundNodeFactory, ArrayBuilder<LocalSymbol>), BoundExpression>(arguments, (Func<BoundExpression, (SyntheticBoundNodeFactory, ArrayBuilder<LocalSymbol>), BoundExpression>)((BoundExpression arg, (SyntheticBoundNodeFactory factory, ArrayBuilder<LocalSymbol> builder) t) => (arg.Kind != BoundKind.DiscardExpression) ? arg : t.factory.MakeTempForDiscard((BoundDiscardExpression)arg, t.builder)), (this, builder));
|
|
}
|
|
return arguments;
|
|
}
|
|
|
|
internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrittenExpr, BinaryOperatorKind operatorKind)
|
|
{
|
|
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0085: Invalid comparison between Unknown and I4
|
|
TypeSymbol type = rewrittenExpr.Type;
|
|
TypeSymbol specialType = Compilation.GetSpecialType((SpecialType)7);
|
|
if (rewrittenExpr.ConstantValueOpt != (ConstantValue)null)
|
|
{
|
|
switch (operatorKind)
|
|
{
|
|
case BinaryOperatorKind.Equal:
|
|
return Literal(ConstantValue.Create((object)rewrittenExpr.ConstantValueOpt.IsNull, (ConstantValueTypeDiscriminator)13), specialType);
|
|
case BinaryOperatorKind.NotEqual:
|
|
return Literal(ConstantValue.Create((object)rewrittenExpr.ConstantValueOpt.IsNull, (ConstantValueTypeDiscriminator)13), specialType);
|
|
}
|
|
}
|
|
TypeSymbol type2 = SpecialType((SpecialType)1);
|
|
if ((object)type != null)
|
|
{
|
|
if ((int)type.Kind == 17)
|
|
{
|
|
rewrittenExpr = Convert(type2, rewrittenExpr, Conversion.Boxing);
|
|
}
|
|
else if (type.IsNullableType())
|
|
{
|
|
operatorKind |= BinaryOperatorKind.NullableNull;
|
|
}
|
|
}
|
|
if (operatorKind == BinaryOperatorKind.NullableNullEqual || operatorKind == BinaryOperatorKind.NullableNullNotEqual)
|
|
{
|
|
return RewriteNullableNullEquality(syntax, operatorKind, rewrittenExpr, Literal(ConstantValue.Null, type2), specialType);
|
|
}
|
|
return Binary(operatorKind, specialType, rewrittenExpr, Null(type2));
|
|
}
|
|
|
|
internal BoundExpression MakeNullableHasValue(SyntaxNode syntax, BoundExpression expression)
|
|
{
|
|
return BoundCall.Synthesized(syntax, expression, (ThreeState)0, LocalRewriter.UnsafeGetNullableMethod(syntax, expression.Type, (SpecialMember)116, Compilation, Diagnostics));
|
|
}
|
|
|
|
internal BoundExpression RewriteNullableNullEquality(SyntaxNode syntax, BinaryOperatorKind kind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol returnType)
|
|
{
|
|
BoundExpression boundExpression = (loweredRight.IsLiteralNull() ? loweredLeft : loweredRight);
|
|
if (LocalRewriter.NullableNeverHasValue(boundExpression))
|
|
{
|
|
return Literal(kind == BinaryOperatorKind.NullableNullEqual);
|
|
}
|
|
BoundExpression boundExpression2 = LocalRewriter.NullableAlwaysHasValue(boundExpression);
|
|
if (boundExpression2 != null)
|
|
{
|
|
return new BoundSequence(syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray.Create(boundExpression2), Literal(kind == BinaryOperatorKind.NullableNullNotEqual), returnType);
|
|
}
|
|
if (boundExpression is BoundLoweredConditionalAccess boundLoweredConditionalAccess && (boundLoweredConditionalAccess.WhenNullOpt == null || boundLoweredConditionalAccess.WhenNullOpt.IsDefaultValue()))
|
|
{
|
|
BoundExpression boundExpression3 = RewriteNullableNullEquality(syntax, kind, boundLoweredConditionalAccess.WhenNotNull, loweredLeft.IsLiteralNull() ? loweredLeft : loweredRight, returnType);
|
|
BoundLiteral whenNullOpt = ((kind == BinaryOperatorKind.NullableNullEqual) ? Literal(value: true) : null);
|
|
return boundLoweredConditionalAccess.Update(boundLoweredConditionalAccess.Receiver, boundLoweredConditionalAccess.HasValueMethodOpt, boundExpression3, whenNullOpt, boundLoweredConditionalAccess.Id, boundLoweredConditionalAccess.ForceCopyOfNullableValueType, boundExpression3.Type);
|
|
}
|
|
BoundExpression boundExpression4 = MakeNullableHasValue(syntax, boundExpression);
|
|
if (kind != BinaryOperatorKind.NullableNullNotEqual)
|
|
{
|
|
return new BoundUnaryOperator(syntax, UnaryOperatorKind.BoolLogicalNegation, boundExpression4, null, null, null, LookupResultKind.Viable, returnType);
|
|
}
|
|
return boundExpression4;
|
|
}
|
|
}
|