From d7b1cefe6485fa4443dd3699dc9e7ba4fb29d1c0 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 13:26:13 +0200 Subject: [PATCH 01/43] inital draft for https://github.com/dotnet/roslyn/issues/48082 --- .../Operations/CSharpOperationFactory.cs | 9 +- .../CSharpOperationFactory_Methods.cs | 12 ++- .../IOperation/FunctionPointerOperations.cs | 97 +++++++++++-------- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 1ffbb4e624eda..5c3a508d03370 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -449,16 +449,17 @@ private IOperation CreateBoundFunctionPointerInvocationOperation(BoundFunctionPo ITypeSymbol? type = boundFunctionPointerInvocation.GetPublicTypeSymbol(); SyntaxNode syntax = boundFunctionPointerInvocation.Syntax; bool isImplicit = boundFunctionPointerInvocation.WasCompilerGenerated; - ImmutableArray children; if (boundFunctionPointerInvocation.ResultKind != LookupResultKind.Viable) { - children = CreateFromArray(((IBoundInvalidNode)boundFunctionPointerInvocation).InvalidNodeChildren); + ImmutableArray children = CreateFromArray(((IBoundInvalidNode)boundFunctionPointerInvocation).InvalidNodeChildren); return new InvalidOperation(children, _semanticModel, syntax, type, constantValue: null, isImplicit); } + var arguments = DeriveArguments(boundFunctionPointerInvocation); + var invoke = new InvocationOperation(boundFunctionPointerInvocation.FunctionPointer.Signature.GetPublicSymbol(), + null, false, arguments, _semanticModel, syntax, type, isImplicit); - children = GetIOperationChildren(boundFunctionPointerInvocation); - return new NoneOperation(children, _semanticModel, syntax, type, constantValue: null, isImplicit); + return invoke; } private IOperation CreateBoundUnconvertedAddressOfOperatorOperation(BoundUnconvertedAddressOfOperator boundUnconvertedAddressOf) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs index d8f22dac45f64..29949cecd5018 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs @@ -259,7 +259,17 @@ internal ImmutableArray DeriveArguments(BoundNode containing boundCollectionElementInitializer.Syntax, boundCollectionElementInitializer.InvokedAsExtensionMethod); } - + case BoundKind.FunctionPointerInvocation: + { + var boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)containingExpression; + return DeriveArguments(boundFunctionPointerInvocation.FunctionPointer.Signature, + boundFunctionPointerInvocation.Arguments, + default, + BitVector.Empty, + false, + boundFunctionPointerInvocation.Syntax, + false); + } default: throw ExceptionUtilities.UnexpectedValue(containingExpression.Kind); } diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 067b8d11b3b5d..568007841ff25 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -201,12 +201,16 @@ void M(delegate* ptr) }"); var expectedOperationTree = @" -IOperation: (OperationKind.None, Type: System.Void) (Syntax: 'ptr(Prop)') - Children(2): - IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') - IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'Prop') - Instance Receiver: - IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'Prop') + IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(Prop)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') + IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'Prop') + Instance Receiver: + IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'Prop') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) "; VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics: new DiagnosticDescription[0]); @@ -326,34 +330,42 @@ void M(delegate* ptr) IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'string s = ptr(Prop)') Declarators: IVariableDeclaratorOperation (Symbol: System.String s) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 's = ptr(Prop)') - Initializer: + Initializer: IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= ptr(Prop)') IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ptr(Prop)') Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - Operand: - IOperation: (OperationKind.None, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Children(2): - IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') - IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') - Instance Receiver: - IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'Prop') - Initializer: + Operand: + IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') + IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') + Instance Receiver: + IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'Prop') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Initializer: null IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 's = ptr(Prop);') - Expression: + Expression: ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, IsInvalid) (Syntax: 's = ptr(Prop)') - Left: + Left: ILocalReferenceOperation: s (OperationKind.LocalReference, Type: System.String) (Syntax: 's') - Right: + Right: IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ptr(Prop)') Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - Operand: - IOperation: (OperationKind.None, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Children(2): - IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') - IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') - Instance Receiver: - IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'Prop') + Operand: + IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') + IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') + Instance Receiver: + IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'Prop') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) "; var expectedDiagnostics = new DiagnosticDescription[] { @@ -463,44 +475,51 @@ static void Test(delegate* ptr, bool b, string s1, string s2) Statements (0) Next (Regular) Block[B1] Entering: {R1} + .locals {R1} { - CaptureIds: [0] [1] + CaptureIds: [0] Block[B1] - Block Predecessors: [B0] - Statements (1) - IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'ptr') - Value: - IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') + Statements (0) Jump if False (Regular) to Block[B3] IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b') + Next (Regular) Block[B2] Block[B2] - Block Predecessors: [B1] Statements (1) - IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's1') - Value: + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's1') + Value: IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1') + Next (Regular) Block[B4] Block[B3] - Block Predecessors: [B1] Statements (1) - IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's2') - Value: + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's2') + Value: IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2') + Next (Regular) Block[B4] Block[B4] - Block Predecessors: [B2] [B3] Statements (1) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'ptr(b ? s1 : s2);') - Expression: - IOperation: (OperationKind.None, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') - Children(2): - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: delegate*, IsImplicit) (Syntax: 'ptr') - IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'b ? s1 : s2') + Expression: + IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'b ? s1 : s2') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'b ? s1 : s2') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B5] Leaving: {R1} } + Block[B5] - Exit Predecessors: [B4] Statements (0) From fe98a28767770aeb78846224f22d339099fa49d6 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 13:32:00 +0200 Subject: [PATCH 02/43] indention --- .../IOperation/FunctionPointerOperations.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 568007841ff25..6c8032bd38ebb 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -201,16 +201,16 @@ void M(delegate* ptr) }"); var expectedOperationTree = @" - IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(Prop)') +IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(Prop)') Instance Receiver: - null + null Arguments(1): - IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') - IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'Prop') - Instance Receiver: - IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'Prop') - InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') + IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'Prop') + Instance Receiver: + IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'Prop') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) "; VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics: new DiagnosticDescription[0]); From 758ba9b316867079c15215618bd53a820e8d8093 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 14:30:52 +0200 Subject: [PATCH 03/43] introduction of an FunctionPointerInvocationOperation (without updating the tests) --- .../Operations/CSharpOperationFactory.cs | 7 +- .../Generated/OperationKind.Generated.cs | 178 +++++++++--------- .../Generated/Operations.Generated.cs | 74 ++++++++ .../Operations/OperationInterfaces.xml | 17 ++ .../Core/Portable/PublicAPI.Unshipped.txt | 5 + 5 files changed, 189 insertions(+), 92 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 5c3a508d03370..65bda8d7f24de 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -455,11 +455,10 @@ private IOperation CreateBoundFunctionPointerInvocationOperation(BoundFunctionPo ImmutableArray children = CreateFromArray(((IBoundInvalidNode)boundFunctionPointerInvocation).InvalidNodeChildren); return new InvalidOperation(children, _semanticModel, syntax, type, constantValue: null, isImplicit); } - var arguments = DeriveArguments(boundFunctionPointerInvocation); - var invoke = new InvocationOperation(boundFunctionPointerInvocation.FunctionPointer.Signature.GetPublicSymbol(), - null, false, arguments, _semanticModel, syntax, type, isImplicit); - return invoke; + var pointer = Create(boundFunctionPointerInvocation.InvokedExpression); + var arguments = DeriveArguments(boundFunctionPointerInvocation); + return new FunctionPointerInvocationOperation(pointer, arguments, _semanticModel, syntax, type, isImplicit); } private IOperation CreateBoundUnconvertedAddressOfOperatorOperation(BoundUnconvertedAddressOfOperator boundUnconvertedAddressOf) diff --git a/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs b/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs index 54e5d98317ec5..d5cc42ea01277 100644 --- a/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs @@ -60,21 +60,21 @@ public enum OperationKind Conversion = 0x15, /// Indicates an . Invocation = 0x16, + /// Indicates an . + FunctionPointerInvocation = 0x17, /// Indicates an . - ArrayElementReference = 0x17, + ArrayElementReference = 0x18, /// Indicates an . - LocalReference = 0x18, + LocalReference = 0x19, /// Indicates an . - ParameterReference = 0x19, + ParameterReference = 0x1a, /// Indicates an . - FieldReference = 0x1a, + FieldReference = 0x1b, /// Indicates an . - MethodReference = 0x1b, - /// Indicates an . - PropertyReference = 0x1c, + MethodReference = 0x1c, // Unused: 1d - /// Indicates an . - EventReference = 0x1e, + /// Indicates an . + PropertyReference = 0x1e, /// Indicates an . Unary = 0x1f, /// Indicates an . Use instead. @@ -85,115 +85,115 @@ public enum OperationKind /// Indicates an . Use instead. [EditorBrowsable(EditorBrowsableState.Never)] BinaryOperator = 0x20, + /// Indicates an . + EventReference = 0x21, /// Indicates an . - Conditional = 0x21, + Conditional = 0x22, /// Indicates an . - Coalesce = 0x22, + Coalesce = 0x23, /// Indicates an . - AnonymousFunction = 0x23, + AnonymousFunction = 0x24, /// Indicates an . - ObjectCreation = 0x24, + ObjectCreation = 0x25, /// Indicates an . - TypeParameterObjectCreation = 0x25, + TypeParameterObjectCreation = 0x26, /// Indicates an . - ArrayCreation = 0x26, + ArrayCreation = 0x27, /// Indicates an . - InstanceReference = 0x27, + InstanceReference = 0x28, /// Indicates an . - IsType = 0x28, + IsType = 0x29, /// Indicates an . - Await = 0x29, + Await = 0x2a, /// Indicates an . - SimpleAssignment = 0x2a, + SimpleAssignment = 0x2b, /// Indicates an . - CompoundAssignment = 0x2b, + CompoundAssignment = 0x2c, /// Indicates an . - Parenthesized = 0x2c, + Parenthesized = 0x2d, /// Indicates an . - EventAssignment = 0x2d, + EventAssignment = 0x2e, /// Indicates an . - ConditionalAccess = 0x2e, + ConditionalAccess = 0x2f, /// Indicates an . - ConditionalAccessInstance = 0x2f, + ConditionalAccessInstance = 0x30, /// Indicates an . - InterpolatedString = 0x30, + InterpolatedString = 0x31, /// Indicates an . - AnonymousObjectCreation = 0x31, + AnonymousObjectCreation = 0x32, /// Indicates an . - ObjectOrCollectionInitializer = 0x32, + ObjectOrCollectionInitializer = 0x33, /// Indicates an . - MemberInitializer = 0x33, + MemberInitializer = 0x34, /// Indicates an . [Obsolete("ICollectionElementInitializerOperation has been replaced with " + nameof(IInvocationOperation) + " and " + nameof(IDynamicInvocationOperation), error: true)] - CollectionElementInitializer = 0x34, + CollectionElementInitializer = 0x35, /// Indicates an . - NameOf = 0x35, + NameOf = 0x36, /// Indicates an . - Tuple = 0x36, + Tuple = 0x37, /// Indicates an . - DynamicObjectCreation = 0x37, + DynamicObjectCreation = 0x38, /// Indicates an . - DynamicMemberReference = 0x38, + DynamicMemberReference = 0x39, /// Indicates an . - DynamicInvocation = 0x39, + DynamicInvocation = 0x3a, /// Indicates an . - DynamicIndexerAccess = 0x3a, + DynamicIndexerAccess = 0x3b, /// Indicates an . - TranslatedQuery = 0x3b, + TranslatedQuery = 0x3c, /// Indicates an . - DelegateCreation = 0x3c, + DelegateCreation = 0x3d, /// Indicates an . - DefaultValue = 0x3d, + DefaultValue = 0x3e, /// Indicates an . - TypeOf = 0x3e, + TypeOf = 0x3f, /// Indicates an . - SizeOf = 0x3f, + SizeOf = 0x40, /// Indicates an . - AddressOf = 0x40, - /// Indicates an . - IsPattern = 0x41, + AddressOf = 0x41, /// Indicates an . This is used as an increment operator Increment = 0x42, - /// Indicates an . - Throw = 0x43, + /// Indicates an . + IsPattern = 0x43, /// Indicates an . This is used as a decrement operator Decrement = 0x44, + /// Indicates an . + Throw = 0x45, /// Indicates an . - DeconstructionAssignment = 0x45, + DeconstructionAssignment = 0x46, /// Indicates an . - DeclarationExpression = 0x46, + DeclarationExpression = 0x47, /// Indicates an . - OmittedArgument = 0x47, + OmittedArgument = 0x48, /// Indicates an . - FieldInitializer = 0x48, + FieldInitializer = 0x49, /// Indicates an . - VariableInitializer = 0x49, + VariableInitializer = 0x4a, /// Indicates an . - PropertyInitializer = 0x4a, + PropertyInitializer = 0x4b, /// Indicates an . - ParameterInitializer = 0x4b, + ParameterInitializer = 0x4c, /// Indicates an . - ArrayInitializer = 0x4c, + ArrayInitializer = 0x4d, /// Indicates an . - VariableDeclarator = 0x4d, + VariableDeclarator = 0x4e, /// Indicates an . - VariableDeclaration = 0x4e, + VariableDeclaration = 0x4f, /// Indicates an . - Argument = 0x4f, + Argument = 0x50, /// Indicates an . - CatchClause = 0x50, + CatchClause = 0x51, /// Indicates an . - SwitchCase = 0x51, + SwitchCase = 0x52, /// Indicates an . This is further differentiated by . - CaseClause = 0x52, + CaseClause = 0x53, /// Indicates an . - InterpolatedStringText = 0x53, + InterpolatedStringText = 0x54, /// Indicates an . - Interpolation = 0x54, + Interpolation = 0x55, /// Indicates an . - ConstantPattern = 0x55, - /// Indicates an . - DeclarationPattern = 0x56, + ConstantPattern = 0x56, /// Indicates an . TupleBinary = 0x57, /// Indicates an . Use instead. @@ -209,51 +209,53 @@ public enum OperationKind /// Indicates an . Use instead. [EditorBrowsable(EditorBrowsableState.Never)] ConstructorBodyOperation = 0x59, + /// Indicates an . + DeclarationPattern = 0x5a, /// Indicates an . - Discard = 0x5a, + Discard = 0x5b, /// Indicates an . - FlowCapture = 0x5b, + FlowCapture = 0x5c, /// Indicates an . - FlowCaptureReference = 0x5c, + FlowCaptureReference = 0x5d, /// Indicates an . - IsNull = 0x5d, + IsNull = 0x5e, /// Indicates an . - CaughtException = 0x5e, + CaughtException = 0x5f, /// Indicates an . - StaticLocalInitializationSemaphore = 0x5f, + StaticLocalInitializationSemaphore = 0x60, /// Indicates an . - FlowAnonymousFunction = 0x60, - /// Indicates an . - CoalesceAssignment = 0x61, + FlowAnonymousFunction = 0x61, // Unused: 62 - /// Indicates an . - Range = 0x63, + /// Indicates an . + CoalesceAssignment = 0x63, // Unused: 64 + /// Indicates an . + Range = 0x65, /// Indicates an . - ReDim = 0x65, + ReDim = 0x66, /// Indicates an . - ReDimClause = 0x66, + ReDimClause = 0x67, /// Indicates an . - RecursivePattern = 0x67, + RecursivePattern = 0x68, /// Indicates an . - DiscardPattern = 0x68, + DiscardPattern = 0x69, /// Indicates an . - SwitchExpression = 0x69, + SwitchExpression = 0x6a, /// Indicates an . - SwitchExpressionArm = 0x6a, + SwitchExpressionArm = 0x6b, /// Indicates an . - PropertySubpattern = 0x6b, + PropertySubpattern = 0x6c, /// Indicates an . - UsingDeclaration = 0x6c, + UsingDeclaration = 0x6d, /// Indicates an . - NegatedPattern = 0x6d, + NegatedPattern = 0x6e, /// Indicates an . - BinaryPattern = 0x6e, + BinaryPattern = 0x6f, /// Indicates an . - TypePattern = 0x6f, + TypePattern = 0x70, /// Indicates an . - RelationalPattern = 0x70, + RelationalPattern = 0x71, /// Indicates an . - With = 0x71, + With = 0x72, } } diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 9b6a2dc961b59..7858ef55f84fe 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -731,6 +731,28 @@ public interface IInvocationOperation : IOperation ImmutableArray Arguments { get; } } /// + /// Represents an invocation of a function pointer. + /// + /// + /// This node is associated with the following operation kinds: + /// + /// + /// + /// This interface is reserved for implementation by its associated APIs. We reserve the right to + /// change it in the future. + /// + public interface IFunctionPointerInvocationOperation : IOperation + { + /// + /// Invoked pointer. + /// + IOperation Pointer { get; } + /// + /// Arguments of the invocation. Arguments are in evaluation order. + /// + ImmutableArray Arguments { get; } + } + /// /// Represents a reference to an array element. /// /// Current usage: @@ -4181,6 +4203,51 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitInvocation(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitInvocation(this, argument); } + internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation + { + internal FunctionPointerInvocationOperation(IOperation pointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) + : base(semanticModel, syntax, isImplicit) + { + Pointer = SetParentOperation(pointer, this); + Arguments = SetParentOperation(arguments, this); + Type = type; + } + public IOperation Pointer { get; } + public ImmutableArray Arguments { get; } + protected override IOperation GetCurrent(int slot, int index) + => slot switch + { + 0 when Pointer != null + => Pointer, + 1 when index < Arguments.Length + => Arguments[index], + _ => throw ExceptionUtilities.UnexpectedValue((slot, index)), + }; + protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) + { + switch (previousSlot) + { + case -1: + if (Pointer != null) return (true, 0, 0); + else goto case 0; + case 0: + if (!Arguments.IsEmpty) return (true, 1, 0); + else goto case 1; + case 1 when previousIndex + 1 < Arguments.Length: + return (true, 1, previousIndex + 1); + case 1: + case 2: + return (false, 2, 0); + default: + throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex)); + } + } + public override ITypeSymbol? Type { get; } + internal override ConstantValue? OperationConstantValue => null; + public override OperationKind Kind => OperationKind.FunctionPointerInvocation; + public override void Accept(OperationVisitor visitor) => visitor.VisitFunctionPointerInvocation(this); + public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitFunctionPointerInvocation(this, argument); + } internal sealed partial class ArrayElementReferenceOperation : Operation, IArrayElementReferenceOperation { internal ArrayElementReferenceOperation(IOperation arrayReference, ImmutableArray indices, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) @@ -7725,6 +7792,11 @@ public override IOperation VisitInvocation(IInvocationOperation operation, objec var internalOperation = (InvocationOperation)operation; return new InvocationOperation(internalOperation.TargetMethod, Visit(internalOperation.Instance), internalOperation.IsVirtual, VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); } + public override IOperation VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, object? argument) + { + var internalOperation = (FunctionPointerInvocationOperation)operation; + return new FunctionPointerInvocationOperation(Visit(internalOperation.Pointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); + } public override IOperation VisitArrayElementReference(IArrayElementReferenceOperation operation, object? argument) { var internalOperation = (ArrayElementReferenceOperation)operation; @@ -8192,6 +8264,7 @@ internal virtual void VisitNoneOperation(IOperation operation) { /* no-op */ } public virtual void VisitLiteral(ILiteralOperation operation) => DefaultVisit(operation); public virtual void VisitConversion(IConversionOperation operation) => DefaultVisit(operation); public virtual void VisitInvocation(IInvocationOperation operation) => DefaultVisit(operation); + public virtual void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) => DefaultVisit(operation); public virtual void VisitArrayElementReference(IArrayElementReferenceOperation operation) => DefaultVisit(operation); public virtual void VisitLocalReference(ILocalReferenceOperation operation) => DefaultVisit(operation); public virtual void VisitParameterReference(IParameterReferenceOperation operation) => DefaultVisit(operation); @@ -8318,6 +8391,7 @@ public abstract partial class OperationVisitor public virtual TResult? VisitLiteral(ILiteralOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitConversion(IConversionOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitInvocation(IInvocationOperation operation, TArgument argument) => DefaultVisit(operation, argument); + public virtual TResult? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitArrayElementReference(IArrayElementReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitLocalReference(ILocalReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitParameterReference(IParameterReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index 0e5bd4528bf3d..859c17a42913a 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -683,6 +683,23 @@ + + + + Represents an invocation of a function pointer. + + + + + Invoked pointer. + + + + + Arguments of the invocation. Arguments are in evaluation order. + + + diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 588f28238c3cb..ce6011d1d717e 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -72,6 +72,9 @@ Microsoft.CodeAnalysis.LineMapping.LineMapping() -> void Microsoft.CodeAnalysis.LineMapping.LineMapping(Microsoft.CodeAnalysis.Text.LinePositionSpan span, int? characterOffset, Microsoft.CodeAnalysis.FileLinePositionSpan mappedSpan) -> void Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.FileLinePositionSpan Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan +Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation +Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray +Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Pointer.get -> Microsoft.CodeAnalysis.IOperation! Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.CollapseTupleTypes = 512 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions override Microsoft.CodeAnalysis.LineMapping.Equals(object? obj) -> bool override Microsoft.CodeAnalysis.LineMapping.GetHashCode() -> int @@ -127,3 +130,5 @@ static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer System.Collections.Immutable.ImmutableArray virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray abstract Microsoft.CodeAnalysis.Compilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray +virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitFunctionPointerInvocation(Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! operation) -> void +virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitFunctionPointerInvocation(Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! operation, TArgument argument) -> TResult? From 165a9213529e0522a92717454dfe9b26141b4808 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 15:08:01 +0200 Subject: [PATCH 04/43] test adjustments for IFunctionPointerInvocationOperation --- .../IOperation/FunctionPointerOperations.cs | 40 ++++++++++--------- .../Operations/ControlFlowGraphBuilder.cs | 10 +++++ .../Compilation/ControlFlowGraphVerifier.cs | 1 + .../Core/Compilation/OperationTreeVerifier.cs | 9 +++++ .../Core/Compilation/TestOperationVisitor.cs | 10 +++++ 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 6c8032bd38ebb..272ead9963c83 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -201,13 +201,13 @@ void M(delegate* ptr) }"); var expectedOperationTree = @" -IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(Prop)') - Instance Receiver: - null +IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(Prop)') + Expression: + IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'Prop') - Instance Receiver: + Instance Receiver: IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'Prop') InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) @@ -335,9 +335,9 @@ void M(delegate* ptr) IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ptr(Prop)') Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: - IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Instance Receiver: - null + IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') + Expression: + IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') @@ -356,9 +356,9 @@ void M(delegate* ptr) IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ptr(Prop)') Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: - IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Instance Receiver: - null + IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') + Expression: + IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') IPropertyReferenceOperation: System.String C.Prop { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid) (Syntax: 'Prop') @@ -478,10 +478,14 @@ static void Test(delegate* ptr, bool b, string s1, string s2) .locals {R1} { - CaptureIds: [0] + CaptureIds: [0] [1] Block[B1] - Block Predecessors: [B0] - Statements (0) + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'ptr') + Value: + IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') + Jump if False (Regular) to Block[B3] IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b') @@ -489,7 +493,7 @@ static void Test(delegate* ptr, bool b, string s1, string s2) Block[B2] - Block Predecessors: [B1] Statements (1) - IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's1') + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's1') Value: IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1') @@ -497,7 +501,7 @@ static void Test(delegate* ptr, bool b, string s1, string s2) Block[B3] - Block Predecessors: [B1] Statements (1) - IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's2') + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's2') Value: IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2') @@ -507,12 +511,12 @@ static void Test(delegate* ptr, bool b, string s1, string s2) Statements (1) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'ptr(b ? s1 : s2);') Expression: - IInvocationOperation (delegate*) (OperationKind.Invocation, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') - Instance Receiver: - null + IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') + Expression: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: delegate*, IsImplicit) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'b ? s1 : s2') - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'b ? s1 : s2') + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'b ? s1 : s2') InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index f61124b1be1b6..68342b08f8f75 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5657,6 +5657,16 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? operation.Type, IsImplicit(operation)); } + public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) + { + EvalStackFrame frame = PushStackFrame(); + IOperation? pointer = operation.Pointer; + (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitInstanceWithArguments(pointer, operation.Arguments); + PopStackFrame(frame); + return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, + operation.Type, IsImplicit(operation)); + } + private (IOperation? visitedInstance, ImmutableArray visitedArguments) VisitInstanceWithArguments(IOperation? instance, ImmutableArray arguments) { if (instance != null) diff --git a/src/Compilers/Test/Core/Compilation/ControlFlowGraphVerifier.cs b/src/Compilers/Test/Core/Compilation/ControlFlowGraphVerifier.cs index 35032082bdf93..e12ac42415140 100644 --- a/src/Compilers/Test/Core/Compilation/ControlFlowGraphVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/ControlFlowGraphVerifier.cs @@ -1836,6 +1836,7 @@ propertyReference.Parent is ISimpleAssignmentOperation simpleAssignment && case OperationKind.None: return !(n is IPlaceholderOperation); + case OperationKind.FunctionPointerInvocation: case OperationKind.Invalid: case OperationKind.YieldReturn: case OperationKind.ExpressionStatement: diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 0c2ee0e26dfeb..38e6f74c6558a 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -824,6 +824,15 @@ public override void VisitInvocation(IInvocationOperation operation) VisitArguments(operation.Arguments); } + public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) + { + LogString(nameof(IFunctionPointerInvocationOperation)); + LogCommonPropertiesAndNewLine(operation); + + Visit(operation.Pointer, "Expression"); + VisitArguments(operation.Arguments); + } + private void VisitArguments(ImmutableArray arguments) { VisitArray(arguments, "Arguments", logElementCount: true); diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 40aa23c5b2db6..e568402f874b3 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -502,6 +502,16 @@ public override void VisitInvocation(IInvocationOperation operation) } } + public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) + { + Assert.Equal(OperationKind.FunctionPointerInvocation, operation.Kind); + Assert.NotNull(operation.Pointer); + + IEnumerable children = new[] { operation.Pointer }.Concat(operation.Arguments); + + AssertEx.Equal(children, operation.Children); + } + public override void VisitArgument(IArgumentOperation operation) { Assert.Equal(OperationKind.Argument, operation.Kind); From 97232e2c94ef43383d6cfbf51eea0e1aebbad64c Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 15:25:40 +0200 Subject: [PATCH 05/43] name adjusted --- .../IOperation/IOperation/FunctionPointerOperations.cs | 8 ++++---- .../Test/Core/Compilation/OperationTreeVerifier.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 272ead9963c83..3a8d3941ace53 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -202,7 +202,7 @@ void M(delegate* ptr) var expectedOperationTree = @" IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(Prop)') - Expression: + Pointer: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') @@ -336,7 +336,7 @@ void M(delegate* ptr) Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Expression: + Pointer: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') @@ -357,7 +357,7 @@ void M(delegate* ptr) Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Expression: + Pointer: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') @@ -512,7 +512,7 @@ static void Test(delegate* ptr, bool b, string s1, string s2) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'ptr(b ? s1 : s2);') Expression: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') - Expression: + Pointer: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: delegate*, IsImplicit) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'b ? s1 : s2') diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 38e6f74c6558a..1252b57636888 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -829,7 +829,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp LogString(nameof(IFunctionPointerInvocationOperation)); LogCommonPropertiesAndNewLine(operation); - Visit(operation.Pointer, "Expression"); + Visit(operation.Pointer, "Pointer"); VisitArguments(operation.Arguments); } From b2151968b4faf05f9b8a2d749f578b5337d1f450 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 15:35:28 +0200 Subject: [PATCH 06/43] fixed API compatibility issue caused by OperationKind-order --- .../Generated/OperationKind.Generated.cs | 180 +++++++++--------- .../Generated/Operations.Generated.cs | 148 +++++++------- .../Operations/OperationInterfaces.xml | 34 ++-- 3 files changed, 181 insertions(+), 181 deletions(-) diff --git a/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs b/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs index d5cc42ea01277..645b3d4be4c62 100644 --- a/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/OperationKind.Generated.cs @@ -60,21 +60,21 @@ public enum OperationKind Conversion = 0x15, /// Indicates an . Invocation = 0x16, - /// Indicates an . - FunctionPointerInvocation = 0x17, /// Indicates an . - ArrayElementReference = 0x18, + ArrayElementReference = 0x17, /// Indicates an . - LocalReference = 0x19, + LocalReference = 0x18, /// Indicates an . - ParameterReference = 0x1a, + ParameterReference = 0x19, /// Indicates an . - FieldReference = 0x1b, + FieldReference = 0x1a, /// Indicates an . - MethodReference = 0x1c, - // Unused: 1d + MethodReference = 0x1b, /// Indicates an . - PropertyReference = 0x1e, + PropertyReference = 0x1c, + // Unused: 1d + /// Indicates an . + EventReference = 0x1e, /// Indicates an . Unary = 0x1f, /// Indicates an . Use instead. @@ -85,115 +85,115 @@ public enum OperationKind /// Indicates an . Use instead. [EditorBrowsable(EditorBrowsableState.Never)] BinaryOperator = 0x20, - /// Indicates an . - EventReference = 0x21, /// Indicates an . - Conditional = 0x22, + Conditional = 0x21, /// Indicates an . - Coalesce = 0x23, + Coalesce = 0x22, /// Indicates an . - AnonymousFunction = 0x24, + AnonymousFunction = 0x23, /// Indicates an . - ObjectCreation = 0x25, + ObjectCreation = 0x24, /// Indicates an . - TypeParameterObjectCreation = 0x26, + TypeParameterObjectCreation = 0x25, /// Indicates an . - ArrayCreation = 0x27, + ArrayCreation = 0x26, /// Indicates an . - InstanceReference = 0x28, + InstanceReference = 0x27, /// Indicates an . - IsType = 0x29, + IsType = 0x28, /// Indicates an . - Await = 0x2a, + Await = 0x29, /// Indicates an . - SimpleAssignment = 0x2b, + SimpleAssignment = 0x2a, /// Indicates an . - CompoundAssignment = 0x2c, + CompoundAssignment = 0x2b, /// Indicates an . - Parenthesized = 0x2d, + Parenthesized = 0x2c, /// Indicates an . - EventAssignment = 0x2e, + EventAssignment = 0x2d, /// Indicates an . - ConditionalAccess = 0x2f, + ConditionalAccess = 0x2e, /// Indicates an . - ConditionalAccessInstance = 0x30, + ConditionalAccessInstance = 0x2f, /// Indicates an . - InterpolatedString = 0x31, + InterpolatedString = 0x30, /// Indicates an . - AnonymousObjectCreation = 0x32, + AnonymousObjectCreation = 0x31, /// Indicates an . - ObjectOrCollectionInitializer = 0x33, + ObjectOrCollectionInitializer = 0x32, /// Indicates an . - MemberInitializer = 0x34, + MemberInitializer = 0x33, /// Indicates an . [Obsolete("ICollectionElementInitializerOperation has been replaced with " + nameof(IInvocationOperation) + " and " + nameof(IDynamicInvocationOperation), error: true)] - CollectionElementInitializer = 0x35, + CollectionElementInitializer = 0x34, /// Indicates an . - NameOf = 0x36, + NameOf = 0x35, /// Indicates an . - Tuple = 0x37, + Tuple = 0x36, /// Indicates an . - DynamicObjectCreation = 0x38, + DynamicObjectCreation = 0x37, /// Indicates an . - DynamicMemberReference = 0x39, + DynamicMemberReference = 0x38, /// Indicates an . - DynamicInvocation = 0x3a, + DynamicInvocation = 0x39, /// Indicates an . - DynamicIndexerAccess = 0x3b, + DynamicIndexerAccess = 0x3a, /// Indicates an . - TranslatedQuery = 0x3c, + TranslatedQuery = 0x3b, /// Indicates an . - DelegateCreation = 0x3d, + DelegateCreation = 0x3c, /// Indicates an . - DefaultValue = 0x3e, + DefaultValue = 0x3d, /// Indicates an . - TypeOf = 0x3f, + TypeOf = 0x3e, /// Indicates an . - SizeOf = 0x40, + SizeOf = 0x3f, /// Indicates an . - AddressOf = 0x41, + AddressOf = 0x40, + /// Indicates an . + IsPattern = 0x41, /// Indicates an . This is used as an increment operator Increment = 0x42, - /// Indicates an . - IsPattern = 0x43, + /// Indicates an . + Throw = 0x43, /// Indicates an . This is used as a decrement operator Decrement = 0x44, - /// Indicates an . - Throw = 0x45, /// Indicates an . - DeconstructionAssignment = 0x46, + DeconstructionAssignment = 0x45, /// Indicates an . - DeclarationExpression = 0x47, + DeclarationExpression = 0x46, /// Indicates an . - OmittedArgument = 0x48, + OmittedArgument = 0x47, /// Indicates an . - FieldInitializer = 0x49, + FieldInitializer = 0x48, /// Indicates an . - VariableInitializer = 0x4a, + VariableInitializer = 0x49, /// Indicates an . - PropertyInitializer = 0x4b, + PropertyInitializer = 0x4a, /// Indicates an . - ParameterInitializer = 0x4c, + ParameterInitializer = 0x4b, /// Indicates an . - ArrayInitializer = 0x4d, + ArrayInitializer = 0x4c, /// Indicates an . - VariableDeclarator = 0x4e, + VariableDeclarator = 0x4d, /// Indicates an . - VariableDeclaration = 0x4f, + VariableDeclaration = 0x4e, /// Indicates an . - Argument = 0x50, + Argument = 0x4f, /// Indicates an . - CatchClause = 0x51, + CatchClause = 0x50, /// Indicates an . - SwitchCase = 0x52, + SwitchCase = 0x51, /// Indicates an . This is further differentiated by . - CaseClause = 0x53, + CaseClause = 0x52, /// Indicates an . - InterpolatedStringText = 0x54, + InterpolatedStringText = 0x53, /// Indicates an . - Interpolation = 0x55, + Interpolation = 0x54, /// Indicates an . - ConstantPattern = 0x56, + ConstantPattern = 0x55, + /// Indicates an . + DeclarationPattern = 0x56, /// Indicates an . TupleBinary = 0x57, /// Indicates an . Use instead. @@ -209,53 +209,53 @@ public enum OperationKind /// Indicates an . Use instead. [EditorBrowsable(EditorBrowsableState.Never)] ConstructorBodyOperation = 0x59, - /// Indicates an . - DeclarationPattern = 0x5a, /// Indicates an . - Discard = 0x5b, + Discard = 0x5a, /// Indicates an . - FlowCapture = 0x5c, + FlowCapture = 0x5b, /// Indicates an . - FlowCaptureReference = 0x5d, + FlowCaptureReference = 0x5c, /// Indicates an . - IsNull = 0x5e, + IsNull = 0x5d, /// Indicates an . - CaughtException = 0x5f, + CaughtException = 0x5e, /// Indicates an . - StaticLocalInitializationSemaphore = 0x60, + StaticLocalInitializationSemaphore = 0x5f, /// Indicates an . - FlowAnonymousFunction = 0x61, - // Unused: 62 + FlowAnonymousFunction = 0x60, /// Indicates an . - CoalesceAssignment = 0x63, - // Unused: 64 + CoalesceAssignment = 0x61, + // Unused: 62 /// Indicates an . - Range = 0x65, + Range = 0x63, + // Unused: 64 /// Indicates an . - ReDim = 0x66, + ReDim = 0x65, /// Indicates an . - ReDimClause = 0x67, + ReDimClause = 0x66, /// Indicates an . - RecursivePattern = 0x68, + RecursivePattern = 0x67, /// Indicates an . - DiscardPattern = 0x69, + DiscardPattern = 0x68, /// Indicates an . - SwitchExpression = 0x6a, + SwitchExpression = 0x69, /// Indicates an . - SwitchExpressionArm = 0x6b, + SwitchExpressionArm = 0x6a, /// Indicates an . - PropertySubpattern = 0x6c, + PropertySubpattern = 0x6b, /// Indicates an . - UsingDeclaration = 0x6d, + UsingDeclaration = 0x6c, /// Indicates an . - NegatedPattern = 0x6e, + NegatedPattern = 0x6d, /// Indicates an . - BinaryPattern = 0x6f, + BinaryPattern = 0x6e, /// Indicates an . - TypePattern = 0x70, + TypePattern = 0x6f, /// Indicates an . - RelationalPattern = 0x71, + RelationalPattern = 0x70, /// Indicates an . - With = 0x72, + With = 0x71, + /// Indicates an . + FunctionPointerInvocation = 0x72, } } diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 7858ef55f84fe..3815cbeb5847d 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -731,28 +731,6 @@ public interface IInvocationOperation : IOperation ImmutableArray Arguments { get; } } /// - /// Represents an invocation of a function pointer. - /// - /// - /// This node is associated with the following operation kinds: - /// - /// - /// - /// This interface is reserved for implementation by its associated APIs. We reserve the right to - /// change it in the future. - /// - public interface IFunctionPointerInvocationOperation : IOperation - { - /// - /// Invoked pointer. - /// - IOperation Pointer { get; } - /// - /// Arguments of the invocation. Arguments are in evaluation order. - /// - ImmutableArray Arguments { get; } - } - /// /// Represents a reference to an array element. /// /// Current usage: @@ -3342,6 +3320,28 @@ public interface IWithOperation : IOperation /// IObjectOrCollectionInitializerOperation Initializer { get; } } + /// + /// Represents an invocation of a function pointer. + /// + /// + /// This node is associated with the following operation kinds: + /// + /// + /// + /// This interface is reserved for implementation by its associated APIs. We reserve the right to + /// change it in the future. + /// + public interface IFunctionPointerInvocationOperation : IOperation + { + /// + /// Invoked pointer. + /// + IOperation Pointer { get; } + /// + /// Arguments of the invocation. Arguments are in evaluation order. + /// + ImmutableArray Arguments { get; } + } #endregion #region Implementations @@ -4203,51 +4203,6 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitInvocation(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitInvocation(this, argument); } - internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation - { - internal FunctionPointerInvocationOperation(IOperation pointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) - : base(semanticModel, syntax, isImplicit) - { - Pointer = SetParentOperation(pointer, this); - Arguments = SetParentOperation(arguments, this); - Type = type; - } - public IOperation Pointer { get; } - public ImmutableArray Arguments { get; } - protected override IOperation GetCurrent(int slot, int index) - => slot switch - { - 0 when Pointer != null - => Pointer, - 1 when index < Arguments.Length - => Arguments[index], - _ => throw ExceptionUtilities.UnexpectedValue((slot, index)), - }; - protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) - { - switch (previousSlot) - { - case -1: - if (Pointer != null) return (true, 0, 0); - else goto case 0; - case 0: - if (!Arguments.IsEmpty) return (true, 1, 0); - else goto case 1; - case 1 when previousIndex + 1 < Arguments.Length: - return (true, 1, previousIndex + 1); - case 1: - case 2: - return (false, 2, 0); - default: - throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex)); - } - } - public override ITypeSymbol? Type { get; } - internal override ConstantValue? OperationConstantValue => null; - public override OperationKind Kind => OperationKind.FunctionPointerInvocation; - public override void Accept(OperationVisitor visitor) => visitor.VisitFunctionPointerInvocation(this); - public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitFunctionPointerInvocation(this, argument); - } internal sealed partial class ArrayElementReferenceOperation : Operation, IArrayElementReferenceOperation { internal ArrayElementReferenceOperation(IOperation arrayReference, ImmutableArray indices, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) @@ -7669,6 +7624,51 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitWith(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitWith(this, argument); } + internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation + { + internal FunctionPointerInvocationOperation(IOperation pointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) + : base(semanticModel, syntax, isImplicit) + { + Pointer = SetParentOperation(pointer, this); + Arguments = SetParentOperation(arguments, this); + Type = type; + } + public IOperation Pointer { get; } + public ImmutableArray Arguments { get; } + protected override IOperation GetCurrent(int slot, int index) + => slot switch + { + 0 when Pointer != null + => Pointer, + 1 when index < Arguments.Length + => Arguments[index], + _ => throw ExceptionUtilities.UnexpectedValue((slot, index)), + }; + protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) + { + switch (previousSlot) + { + case -1: + if (Pointer != null) return (true, 0, 0); + else goto case 0; + case 0: + if (!Arguments.IsEmpty) return (true, 1, 0); + else goto case 1; + case 1 when previousIndex + 1 < Arguments.Length: + return (true, 1, previousIndex + 1); + case 1: + case 2: + return (false, 2, 0); + default: + throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex)); + } + } + public override ITypeSymbol? Type { get; } + internal override ConstantValue? OperationConstantValue => null; + public override OperationKind Kind => OperationKind.FunctionPointerInvocation; + public override void Accept(OperationVisitor visitor) => visitor.VisitFunctionPointerInvocation(this); + public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitFunctionPointerInvocation(this, argument); + } #endregion #region Cloner internal sealed partial class OperationCloner : OperationVisitor @@ -7792,11 +7792,6 @@ public override IOperation VisitInvocation(IInvocationOperation operation, objec var internalOperation = (InvocationOperation)operation; return new InvocationOperation(internalOperation.TargetMethod, Visit(internalOperation.Instance), internalOperation.IsVirtual, VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); } - public override IOperation VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, object? argument) - { - var internalOperation = (FunctionPointerInvocationOperation)operation; - return new FunctionPointerInvocationOperation(Visit(internalOperation.Pointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); - } public override IOperation VisitArrayElementReference(IArrayElementReferenceOperation operation, object? argument) { var internalOperation = (ArrayElementReferenceOperation)operation; @@ -8232,6 +8227,11 @@ public override IOperation VisitWith(IWithOperation operation, object? argument) var internalOperation = (WithOperation)operation; return new WithOperation(Visit(internalOperation.Operand), internalOperation.CloneMethod, Visit(internalOperation.Initializer), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); } + public override IOperation VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, object? argument) + { + var internalOperation = (FunctionPointerInvocationOperation)operation; + return new FunctionPointerInvocationOperation(Visit(internalOperation.Pointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); + } } #endregion @@ -8264,7 +8264,6 @@ internal virtual void VisitNoneOperation(IOperation operation) { /* no-op */ } public virtual void VisitLiteral(ILiteralOperation operation) => DefaultVisit(operation); public virtual void VisitConversion(IConversionOperation operation) => DefaultVisit(operation); public virtual void VisitInvocation(IInvocationOperation operation) => DefaultVisit(operation); - public virtual void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) => DefaultVisit(operation); public virtual void VisitArrayElementReference(IArrayElementReferenceOperation operation) => DefaultVisit(operation); public virtual void VisitLocalReference(ILocalReferenceOperation operation) => DefaultVisit(operation); public virtual void VisitParameterReference(IParameterReferenceOperation operation) => DefaultVisit(operation); @@ -8362,6 +8361,7 @@ internal virtual void VisitNoneOperation(IOperation operation) { /* no-op */ } public virtual void VisitTypePattern(ITypePatternOperation operation) => DefaultVisit(operation); public virtual void VisitRelationalPattern(IRelationalPatternOperation operation) => DefaultVisit(operation); public virtual void VisitWith(IWithOperation operation) => DefaultVisit(operation); + public virtual void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) => DefaultVisit(operation); } public abstract partial class OperationVisitor { @@ -8391,7 +8391,6 @@ public abstract partial class OperationVisitor public virtual TResult? VisitLiteral(ILiteralOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitConversion(IConversionOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitInvocation(IInvocationOperation operation, TArgument argument) => DefaultVisit(operation, argument); - public virtual TResult? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitArrayElementReference(IArrayElementReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitLocalReference(ILocalReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitParameterReference(IParameterReferenceOperation operation, TArgument argument) => DefaultVisit(operation, argument); @@ -8489,6 +8488,7 @@ public abstract partial class OperationVisitor public virtual TResult? VisitTypePattern(ITypePatternOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitRelationalPattern(IRelationalPatternOperation operation, TArgument argument) => DefaultVisit(operation, argument); public virtual TResult? VisitWith(IWithOperation operation, TArgument argument) => DefaultVisit(operation, argument); + public virtual TResult? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, TArgument argument) => DefaultVisit(operation, argument); } #endregion } diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index 859c17a42913a..c9f0275fff20b 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -683,23 +683,6 @@ - - - - Represents an invocation of a function pointer. - - - - - Invoked pointer. - - - - - Arguments of the invocation. Arguments are in evaluation order. - - - @@ -3074,4 +3057,21 @@ + + + + Represents an invocation of a function pointer. + + + + + Invoked pointer. + + + + + Arguments of the invocation. Arguments are in evaluation order. + + + From 89857b57b19e78d0bc15899380c3ca48cc950630 Mon Sep 17 00:00:00 2001 From: bernd Date: Sun, 17 Oct 2021 17:50:19 +0200 Subject: [PATCH 07/43] FunctionPointerInvocation --- src/Compilers/Core/Portable/PublicAPI.Unshipped.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index ce6011d1d717e..4876038f11d0a 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -75,6 +75,7 @@ Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LineP Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Pointer.get -> Microsoft.CodeAnalysis.IOperation! +Microsoft.CodeAnalysis.OperationKind.FunctionPointerInvocation = 114 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.CollapseTupleTypes = 512 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions override Microsoft.CodeAnalysis.LineMapping.Equals(object? obj) -> bool override Microsoft.CodeAnalysis.LineMapping.GetHashCode() -> int From 5a22df64af44392c55e35d457db75a9c92651675 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 19 Oct 2021 10:07:33 +0200 Subject: [PATCH 08/43] IFunctionPointerInvocationOperation.Pointer -> IFunctionPointerInvocationOperation.InvokedPointer --- .../Portable/Generated/Operations.Generated.cs | 16 ++++++++-------- .../Operations/ControlFlowGraphBuilder.cs | 2 +- .../Portable/Operations/OperationInterfaces.xml | 4 ++-- .../Core/Portable/PublicAPI.Unshipped.txt | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 3815cbeb5847d..3ca8739a292d5 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -3336,7 +3336,7 @@ public interface IFunctionPointerInvocationOperation : IOperation /// /// Invoked pointer. /// - IOperation Pointer { get; } + IOperation InvokedPointer { get; } /// /// Arguments of the invocation. Arguments are in evaluation order. /// @@ -7626,20 +7626,20 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev } internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation { - internal FunctionPointerInvocationOperation(IOperation pointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) + internal FunctionPointerInvocationOperation(IOperation invokedPointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) { - Pointer = SetParentOperation(pointer, this); + InvokedPointer = SetParentOperation(invokedPointer, this); Arguments = SetParentOperation(arguments, this); Type = type; } - public IOperation Pointer { get; } + public IOperation InvokedPointer { get; } public ImmutableArray Arguments { get; } protected override IOperation GetCurrent(int slot, int index) => slot switch { - 0 when Pointer != null - => Pointer, + 0 when InvokedPointer != null + => InvokedPointer, 1 when index < Arguments.Length => Arguments[index], _ => throw ExceptionUtilities.UnexpectedValue((slot, index)), @@ -7649,7 +7649,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev switch (previousSlot) { case -1: - if (Pointer != null) return (true, 0, 0); + if (InvokedPointer != null) return (true, 0, 0); else goto case 0; case 0: if (!Arguments.IsEmpty) return (true, 1, 0); @@ -8230,7 +8230,7 @@ public override IOperation VisitWith(IWithOperation operation, object? argument) public override IOperation VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, object? argument) { var internalOperation = (FunctionPointerInvocationOperation)operation; - return new FunctionPointerInvocationOperation(Visit(internalOperation.Pointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); + return new FunctionPointerInvocationOperation(Visit(internalOperation.InvokedPointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); } } #endregion diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 68342b08f8f75..439f92e9bf4b7 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5660,7 +5660,7 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); - IOperation? pointer = operation.Pointer; + IOperation? pointer = operation.InvokedPointer; (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitInstanceWithArguments(pointer, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index c9f0275fff20b..352278d59d069 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -3057,13 +3057,13 @@ - + Represents an invocation of a function pointer. - + Invoked pointer. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 4876038f11d0a..631a10b9cd690 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -74,7 +74,7 @@ Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.File Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray -Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Pointer.get -> Microsoft.CodeAnalysis.IOperation! +Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.InvokedPointer.get -> Microsoft.CodeAnalysis.IOperation! Microsoft.CodeAnalysis.OperationKind.FunctionPointerInvocation = 114 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.CollapseTupleTypes = 512 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions override Microsoft.CodeAnalysis.LineMapping.Equals(object? obj) -> bool From a12bee42a72e60e42ec0f8dc741a8e74866c56ca Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 19 Oct 2021 12:03:48 +0200 Subject: [PATCH 09/43] IFunctionPointerInvocationOperation.Pointer -> IFunctionPointerInvocationOperation.InvokedPointer --- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index e568402f874b3..d766270ddf93d 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -505,9 +505,9 @@ public override void VisitInvocation(IInvocationOperation operation) public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) { Assert.Equal(OperationKind.FunctionPointerInvocation, operation.Kind); - Assert.NotNull(operation.Pointer); + Assert.NotNull(operation.InvokedPointer); - IEnumerable children = new[] { operation.Pointer }.Concat(operation.Arguments); + IEnumerable children = new[] { operation.InvokedPointer }.Concat(operation.Arguments); AssertEx.Equal(children, operation.Children); } From 4c6c87054574bcf120c222b04108427c7e3c9c10 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 19 Oct 2021 22:18:14 +0200 Subject: [PATCH 10/43] IFunctionPointerInvocationOperation.Pointer -> IFunctionPointerInvocationOperation.InvokedPointer --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 1252b57636888..df831f7712f97 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -829,7 +829,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp LogString(nameof(IFunctionPointerInvocationOperation)); LogCommonPropertiesAndNewLine(operation); - Visit(operation.Pointer, "Pointer"); + Visit(operation.InvokedPointer, "Pointer"); VisitArguments(operation.Arguments); } From 39118dde7167e23f4aaa65465eb69731252630cb Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 09:21:05 +0200 Subject: [PATCH 11/43] base interface try --- .../Generated/Operations.Generated.cs | 26 ++++++++++++++----- .../Operations/OperationInterfaces.xml | 18 ++++++++++--- .../Core/Portable/PublicAPI.Unshipped.txt | 2 ++ .../CompilerGeneratorTools/CompilerTools.sln | 8 +++--- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 3ca8739a292d5..1a571d0eef0a1 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -605,7 +605,7 @@ public interface IEndOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IRaiseEventOperation : IOperation + public interface IRaiseEventOperation : IArgumentProvidingOperation { /// /// Reference to the event to be raised. @@ -618,7 +618,7 @@ public interface IRaiseEventOperation : IOperation /// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays. /// Default values are supplied for optional arguments missing in source. /// - ImmutableArray Arguments { get; } + ImmutableArray IArgumentProvidingOperation.Arguments { get; } } /// /// Represents a textual literal numeric, string, etc. @@ -707,7 +707,7 @@ public interface IConversionOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IInvocationOperation : IOperation + public interface IInvocationOperation : IArgumentProvidingOperation { /// /// Method to be invoked. @@ -809,6 +809,20 @@ public interface IParameterReferenceOperation : IOperation IParameterSymbol Parameter { get; } } /// + /// Common interface to represent operations with arguments + /// + /// + /// This interface is reserved for implementation by its associated APIs. We reserve the right to + /// change it in the future. + /// + public interface IArgumentProvidingOperation : IOperation + { + /// + /// Arguments of the operation. + /// + ImmutableArray Arguments { get; } + } + /// /// Represents a reference to a member of a class, struct, or interface. /// /// Current usage: @@ -3331,7 +3345,7 @@ public interface IWithOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IFunctionPointerInvocationOperation : IOperation + public interface IFunctionPointerInvocationOperation : IArgumentProvidingOperation { /// /// Invoked pointer. @@ -4154,7 +4168,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitConversion(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConversion(this, argument); } - internal sealed partial class InvocationOperation : Operation, IInvocationOperation + internal sealed partial class InvocationOperation : BaseArgumentProvidingOperation, IInvocationOperation { internal InvocationOperation(IMethodSymbol targetMethod, IOperation? instance, bool isVirtual, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) @@ -7624,7 +7638,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitWith(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitWith(this, argument); } - internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation + internal sealed partial class FunctionPointerInvocationOperation : BaseArgumentProvidingOperation, IFunctionPointerInvocationOperation { internal FunctionPointerInvocationOperation(IOperation invokedPointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index 352278d59d069..70644fb68dd2c 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -558,7 +558,7 @@ - + Represents an operation for raising an event. @@ -640,7 +640,7 @@ - + Represents an invocation of a method. @@ -747,6 +747,18 @@ + + + + Common interface to represent operations with arguments + + + + + Arguments of the operation. + + + @@ -3057,7 +3069,7 @@ - + Represents an invocation of a function pointer. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 631a10b9cd690..e03702d034c7a 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -72,6 +72,8 @@ Microsoft.CodeAnalysis.LineMapping.LineMapping() -> void Microsoft.CodeAnalysis.LineMapping.LineMapping(Microsoft.CodeAnalysis.Text.LinePositionSpan span, int? characterOffset, Microsoft.CodeAnalysis.FileLinePositionSpan mappedSpan) -> void Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.FileLinePositionSpan Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan +Microsoft.CodeAnalysis.Operations.IArgumentProvidingOperation +Microsoft.CodeAnalysis.Operations.IArgumentProvidingOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.InvokedPointer.get -> Microsoft.CodeAnalysis.IOperation! diff --git a/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln b/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln index d437aebdfd923..4601ab19646bc 100644 --- a/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln +++ b/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29323.36 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31815.197 MinimumVisualStudioVersion = 10.0.40219.1 Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "VisualBasicSyntaxGenerator", "Source\VisualBasicSyntaxGenerator\VisualBasicSyntaxGenerator.vbproj", "{6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}" EndProject @@ -25,8 +25,8 @@ Global {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Debug|Any CPU.Build.0 = Debug|x64 {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Release|Any CPU.ActiveCfg = Release|x64 {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Release|Any CPU.Build.0 = Release|x64 - {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.ActiveCfg = Debug|x64 - {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.Build.0 = Debug|x64 + {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU {288089C5-8721-458E-BE3E-78990DAB5E2D}.Release|Any CPU.ActiveCfg = Release|x64 {288089C5-8721-458E-BE3E-78990DAB5E2D}.Release|Any CPU.Build.0 = Release|x64 {02459936-CD2C-4F61-B671-5C518F2A3DDC}.Debug|Any CPU.ActiveCfg = Debug|x64 From b7b1d88885dee84dc2461190812c2b1344ed8b74 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 09:21:21 +0200 Subject: [PATCH 12/43] Revert "base interface try" This reverts commit 39118dde7167e23f4aaa65465eb69731252630cb. --- .../Generated/Operations.Generated.cs | 26 +++++-------------- .../Operations/OperationInterfaces.xml | 18 +++---------- .../Core/Portable/PublicAPI.Unshipped.txt | 2 -- .../CompilerGeneratorTools/CompilerTools.sln | 8 +++--- 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 1a571d0eef0a1..3ca8739a292d5 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -605,7 +605,7 @@ public interface IEndOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IRaiseEventOperation : IArgumentProvidingOperation + public interface IRaiseEventOperation : IOperation { /// /// Reference to the event to be raised. @@ -618,7 +618,7 @@ public interface IRaiseEventOperation : IArgumentProvidingOperation /// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays. /// Default values are supplied for optional arguments missing in source. /// - ImmutableArray IArgumentProvidingOperation.Arguments { get; } + ImmutableArray Arguments { get; } } /// /// Represents a textual literal numeric, string, etc. @@ -707,7 +707,7 @@ public interface IConversionOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IInvocationOperation : IArgumentProvidingOperation + public interface IInvocationOperation : IOperation { /// /// Method to be invoked. @@ -809,20 +809,6 @@ public interface IParameterReferenceOperation : IOperation IParameterSymbol Parameter { get; } } /// - /// Common interface to represent operations with arguments - /// - /// - /// This interface is reserved for implementation by its associated APIs. We reserve the right to - /// change it in the future. - /// - public interface IArgumentProvidingOperation : IOperation - { - /// - /// Arguments of the operation. - /// - ImmutableArray Arguments { get; } - } - /// /// Represents a reference to a member of a class, struct, or interface. /// /// Current usage: @@ -3345,7 +3331,7 @@ public interface IWithOperation : IOperation /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// - public interface IFunctionPointerInvocationOperation : IArgumentProvidingOperation + public interface IFunctionPointerInvocationOperation : IOperation { /// /// Invoked pointer. @@ -4168,7 +4154,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitConversion(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConversion(this, argument); } - internal sealed partial class InvocationOperation : BaseArgumentProvidingOperation, IInvocationOperation + internal sealed partial class InvocationOperation : Operation, IInvocationOperation { internal InvocationOperation(IMethodSymbol targetMethod, IOperation? instance, bool isVirtual, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) @@ -7638,7 +7624,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev public override void Accept(OperationVisitor visitor) => visitor.VisitWith(this); public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitWith(this, argument); } - internal sealed partial class FunctionPointerInvocationOperation : BaseArgumentProvidingOperation, IFunctionPointerInvocationOperation + internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation { internal FunctionPointerInvocationOperation(IOperation invokedPointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index 70644fb68dd2c..352278d59d069 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -558,7 +558,7 @@ - + Represents an operation for raising an event. @@ -640,7 +640,7 @@ - + Represents an invocation of a method. @@ -747,18 +747,6 @@ - - - - Common interface to represent operations with arguments - - - - - Arguments of the operation. - - - @@ -3069,7 +3057,7 @@ - + Represents an invocation of a function pointer. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index e03702d034c7a..631a10b9cd690 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -72,8 +72,6 @@ Microsoft.CodeAnalysis.LineMapping.LineMapping() -> void Microsoft.CodeAnalysis.LineMapping.LineMapping(Microsoft.CodeAnalysis.Text.LinePositionSpan span, int? characterOffset, Microsoft.CodeAnalysis.FileLinePositionSpan mappedSpan) -> void Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.FileLinePositionSpan Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan -Microsoft.CodeAnalysis.Operations.IArgumentProvidingOperation -Microsoft.CodeAnalysis.Operations.IArgumentProvidingOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.InvokedPointer.get -> Microsoft.CodeAnalysis.IOperation! diff --git a/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln b/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln index 4601ab19646bc..d437aebdfd923 100644 --- a/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln +++ b/src/Tools/Source/CompilerGeneratorTools/CompilerTools.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31815.197 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29323.36 MinimumVisualStudioVersion = 10.0.40219.1 Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "VisualBasicSyntaxGenerator", "Source\VisualBasicSyntaxGenerator\VisualBasicSyntaxGenerator.vbproj", "{6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}" EndProject @@ -25,8 +25,8 @@ Global {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Debug|Any CPU.Build.0 = Debug|x64 {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Release|Any CPU.ActiveCfg = Release|x64 {6AA96934-D6B7-4CC8-990D-DB6B9DD56E34}.Release|Any CPU.Build.0 = Release|x64 - {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.ActiveCfg = Debug|x64 + {288089C5-8721-458E-BE3E-78990DAB5E2D}.Debug|Any CPU.Build.0 = Debug|x64 {288089C5-8721-458E-BE3E-78990DAB5E2D}.Release|Any CPU.ActiveCfg = Release|x64 {288089C5-8721-458E-BE3E-78990DAB5E2D}.Release|Any CPU.Build.0 = Release|x64 {02459936-CD2C-4F61-B671-5C518F2A3DDC}.Debug|Any CPU.ActiveCfg = Debug|x64 From 878ce2387b29bde79f639552ae2312e4b8c145f9 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 09:58:23 +0200 Subject: [PATCH 13/43] IFunctionPointerInvocationOperation.InvokedPointer -> IFunctionPointerInvocationOperation.Target --- .../Portable/Generated/Operations.Generated.cs | 16 ++++++++-------- .../Operations/ControlFlowGraphBuilder.cs | 2 +- .../Portable/Operations/OperationExtensions.cs | 8 ++++++++ .../Portable/Operations/OperationInterfaces.xml | 4 ++-- .../Core/Portable/PublicAPI.Unshipped.txt | 2 +- .../Core/Compilation/OperationTreeVerifier.cs | 2 +- .../Core/Compilation/TestOperationVisitor.cs | 4 ++-- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs index 3ca8739a292d5..323e445280979 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.Generated.cs @@ -3336,7 +3336,7 @@ public interface IFunctionPointerInvocationOperation : IOperation /// /// Invoked pointer. /// - IOperation InvokedPointer { get; } + IOperation Target { get; } /// /// Arguments of the invocation. Arguments are in evaluation order. /// @@ -7626,20 +7626,20 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev } internal sealed partial class FunctionPointerInvocationOperation : Operation, IFunctionPointerInvocationOperation { - internal FunctionPointerInvocationOperation(IOperation invokedPointer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) + internal FunctionPointerInvocationOperation(IOperation target, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit) : base(semanticModel, syntax, isImplicit) { - InvokedPointer = SetParentOperation(invokedPointer, this); + Target = SetParentOperation(target, this); Arguments = SetParentOperation(arguments, this); Type = type; } - public IOperation InvokedPointer { get; } + public IOperation Target { get; } public ImmutableArray Arguments { get; } protected override IOperation GetCurrent(int slot, int index) => slot switch { - 0 when InvokedPointer != null - => InvokedPointer, + 0 when Target != null + => Target, 1 when index < Arguments.Length => Arguments[index], _ => throw ExceptionUtilities.UnexpectedValue((slot, index)), @@ -7649,7 +7649,7 @@ protected override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int prev switch (previousSlot) { case -1: - if (InvokedPointer != null) return (true, 0, 0); + if (Target != null) return (true, 0, 0); else goto case 0; case 0: if (!Arguments.IsEmpty) return (true, 1, 0); @@ -8230,7 +8230,7 @@ public override IOperation VisitWith(IWithOperation operation, object? argument) public override IOperation VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, object? argument) { var internalOperation = (FunctionPointerInvocationOperation)operation; - return new FunctionPointerInvocationOperation(Visit(internalOperation.InvokedPointer), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); + return new FunctionPointerInvocationOperation(Visit(internalOperation.Target), VisitArray(internalOperation.Arguments), internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit); } } #endregion diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 439f92e9bf4b7..d85670be08be2 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5660,7 +5660,7 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); - IOperation? pointer = operation.InvokedPointer; + IOperation? pointer = operation.Target; (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitInstanceWithArguments(pointer, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, diff --git a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs index d6828dfa9fd9e..766431c4a3d17 100644 --- a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs +++ b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs @@ -14,6 +14,14 @@ namespace Microsoft.CodeAnalysis.Operations { public static partial class OperationExtensions { + /// + /// Helper function to simplify the access to the function pointer signature of an FunctionPointerInvocationOperation + /// + public static IMethodSymbol GetFunctionPointerSignature(this IFunctionPointerInvocationOperation functionPointer) + { + return ((IFunctionPointerTypeSymbol)functionPointer.Target.Type!).Signature; + } + /// /// This will check whether context around the operation has any error such as syntax or semantic error /// diff --git a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml index 352278d59d069..0c7712f38171c 100644 --- a/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml +++ b/src/Compilers/Core/Portable/Operations/OperationInterfaces.xml @@ -3057,13 +3057,13 @@ - + Represents an invocation of a function pointer. - + Invoked pointer. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 631a10b9cd690..148f8904f8bab 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -74,7 +74,7 @@ Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.File Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray -Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.InvokedPointer.get -> Microsoft.CodeAnalysis.IOperation! +Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Target.get -> Microsoft.CodeAnalysis.IOperation! Microsoft.CodeAnalysis.OperationKind.FunctionPointerInvocation = 114 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.CollapseTupleTypes = 512 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions override Microsoft.CodeAnalysis.LineMapping.Equals(object? obj) -> bool diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index df831f7712f97..14ad0825fd436 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -829,7 +829,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp LogString(nameof(IFunctionPointerInvocationOperation)); LogCommonPropertiesAndNewLine(operation); - Visit(operation.InvokedPointer, "Pointer"); + Visit(operation.Target, "Pointer"); VisitArguments(operation.Arguments); } diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index d766270ddf93d..a1c5300921171 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -505,9 +505,9 @@ public override void VisitInvocation(IInvocationOperation operation) public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation) { Assert.Equal(OperationKind.FunctionPointerInvocation, operation.Kind); - Assert.NotNull(operation.InvokedPointer); + Assert.NotNull(operation.Target); - IEnumerable children = new[] { operation.InvokedPointer }.Concat(operation.Arguments); + IEnumerable children = new[] { operation.Target }.Concat(operation.Arguments); AssertEx.Equal(children, operation.Children); } From d0a22f329b58ccd8f6a09f77b9b3c7d66b1619e4 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 10:06:40 +0200 Subject: [PATCH 14/43] static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature --- src/Compilers/Core/Portable/PublicAPI.Unshipped.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 148f8904f8bab..ec062d040fc3c 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -128,6 +128,7 @@ static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.SelectMany(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Func! predicate) -> Microsoft.CodeAnalysis.IncrementalValuesProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValueProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValueProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValuesProvider +static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature(this Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! functionPointer) -> Microsoft.CodeAnalysis.IMethodSymbol! virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGenerators(string! language) -> System.Collections.Immutable.ImmutableArray virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray abstract Microsoft.CodeAnalysis.Compilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray From 352ffeb85d367d9e71d3df99815f7aa72e942230 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 20:42:26 +0200 Subject: [PATCH 15/43] Pointer -> Target --- .../IOperation/IOperation/FunctionPointerOperations.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 3a8d3941ace53..60265df646336 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -202,7 +202,7 @@ void M(delegate* ptr) var expectedOperationTree = @" IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(Prop)') - Pointer: + Target: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'Prop') @@ -336,7 +336,7 @@ void M(delegate* ptr) Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Pointer: + Target: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') @@ -357,7 +357,7 @@ void M(delegate* ptr) Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32, IsInvalid) (Syntax: 'ptr(Prop)') - Pointer: + Target: IParameterReferenceOperation: ptr (OperationKind.ParameterReference, Type: delegate*, IsInvalid) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null, IsInvalid) (Syntax: 'Prop') @@ -512,7 +512,7 @@ static void Test(delegate* ptr, bool b, string s1, string s2) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'ptr(b ? s1 : s2);') Expression: IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Void) (Syntax: 'ptr(b ? s1 : s2)') - Pointer: + Target: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: delegate*, IsImplicit) (Syntax: 'ptr') Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'b ? s1 : s2') From 4fad1bb4e20adadd52afbb2bdc41f9e87450de20 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 20:47:10 +0200 Subject: [PATCH 16/43] Pointer -> Target --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 362df66a05dfc..0ec6f53389533 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -829,7 +829,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp LogString(nameof(IFunctionPointerInvocationOperation)); LogCommonPropertiesAndNewLine(operation); - Visit(operation.Target, "Pointer"); + Visit(operation.Target, "Target"); VisitArguments(operation.Arguments); } From 585c9450687456cb2d4eeab3747fe9488c9bd488 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 21:01:51 +0200 Subject: [PATCH 17/43] API Change --- src/Compilers/Core/Portable/PublicAPI.Unshipped.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index a8b7e7b952529..e817d168f19cf 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -72,10 +72,10 @@ Microsoft.CodeAnalysis.LineMapping.LineMapping() -> void Microsoft.CodeAnalysis.LineMapping.LineMapping(Microsoft.CodeAnalysis.Text.LinePositionSpan span, int? characterOffset, Microsoft.CodeAnalysis.FileLinePositionSpan mappedSpan) -> void Microsoft.CodeAnalysis.LineMapping.MappedSpan.get -> Microsoft.CodeAnalysis.FileLinePositionSpan Microsoft.CodeAnalysis.LineMapping.Span.get -> Microsoft.CodeAnalysis.Text.LinePositionSpan +Microsoft.CodeAnalysis.OperationKind.FunctionPointerInvocation = 120 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Arguments.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation.Target.get -> Microsoft.CodeAnalysis.IOperation! -Microsoft.CodeAnalysis.OperationKind.FunctionPointerInvocation = 114 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.InterpolatedStringAddition = 115 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.InterpolatedStringAppendFormatted = 117 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.InterpolatedStringAppendInvalid = 118 -> Microsoft.CodeAnalysis.OperationKind From 84d369f63ee862c0ed8012f8735af6ecc99d375d Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 22:56:02 +0200 Subject: [PATCH 18/43] used GetFunctionPointerSignature in TestOperationVisitor --- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 9ba7fd7952e9a..0c4100cf39e73 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -509,6 +509,10 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp IEnumerable children = new[] { operation.Target }.Concat(operation.Arguments); + var signature = operation.GetFunctionPointerSignature(); + Assert.NotNull(signature); + Assert.Equal(((IFunctionPointerTypeSymbol)operation.Target.Type!).Signature, signature); + AssertEx.Equal(children, operation.Children); } From 24d84777bf9350d2476390e030aee46eb220586c Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 23:02:47 +0200 Subject: [PATCH 19/43] test added --- .../IOperation/FunctionPointerOperations.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 60265df646336..9319081242632 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -187,6 +188,28 @@ static void M2() VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics); } + [Fact] + public void FunctionPointerInvocationSignatureTest() + { + var comp = CreateFunctionPointerCompilation(@" +unsafe class C +{ + public string Prop { get; } + void M(delegate* ptr) + { + /**/ptr(Prop)/**/; + } +}"); + var (actualOperation, syntaxNode) = GetOperationAndSyntaxForTest(comp); + + var fktPointerOp = (IFunctionPointerInvocationOperation)actualOperation; + var signature = fktPointerOp.GetFunctionPointerSignature(); + + Assert.Equal(1, signature.Parameters.Length); + Assert.True(signature.Parameters[0].Type.SpecialType == SpecialType.System_String); + Assert.True(signature.ReturnType.SpecialType == SpecialType.System_Void); + } + [Fact] public void FunctionPointerInvocation() { From 52dd8f0a563f662bfd40c4430fab0f8ca904a3fa Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 23:04:15 +0200 Subject: [PATCH 20/43] test added --- .../Test/IOperation/IOperation/FunctionPointerOperations.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index 9319081242632..ca659f557be3f 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -205,9 +205,10 @@ void M(delegate* ptr) var fktPointerOp = (IFunctionPointerInvocationOperation)actualOperation; var signature = fktPointerOp.GetFunctionPointerSignature(); + Assert.NotNull(syntaxNode); Assert.Equal(1, signature.Parameters.Length); - Assert.True(signature.Parameters[0].Type.SpecialType == SpecialType.System_String); - Assert.True(signature.ReturnType.SpecialType == SpecialType.System_Void); + Assert.Equal(SpecialType.System_String, signature.Parameters[0].Type.SpecialType); + Assert.Equal(SpecialType.System_Void, signature.ReturnType.SpecialType); } [Fact] From df5aa0133fba97eae6da6c08ea8a087f0f97a7d1 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 23:07:59 +0200 Subject: [PATCH 21/43] created function VisitFunctionPointerWithArguments --- .../Operations/ControlFlowGraphBuilder.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index c9882b1678160..a5fc6732fabc8 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5657,11 +5657,24 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? operation.Type, IsImplicit(operation)); } + private (IOperation? visitedInstance, ImmutableArray visitedArguments) VisitFunctionPointerWithArguments(IOperation? instance, ImmutableArray arguments) + { + if (instance != null) + { + PushOperand(VisitRequired(instance)); + } + + ImmutableArray visitedArguments = VisitArguments(arguments); + IOperation? visitedInstance = instance == null ? null : PopOperand(); + + return (visitedInstance, visitedArguments); + } + public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); IOperation? pointer = operation.Target; - (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitInstanceWithArguments(pointer, operation.Arguments); + (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitFunctionPointerWithArguments(pointer, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, operation.Type, IsImplicit(operation)); From 7aea4459b2610a78a94013dbd367659204b56a42 Mon Sep 17 00:00:00 2001 From: bernd Date: Fri, 29 Oct 2021 23:09:19 +0200 Subject: [PATCH 22/43] created function VisitFunctionPointerWithArguments --- .../Core/Portable/Operations/ControlFlowGraphBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index a5fc6732fabc8..41dcc786a4051 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5673,8 +5673,8 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); - IOperation? pointer = operation.Target; - (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitFunctionPointerWithArguments(pointer, operation.Arguments); + IOperation? target = operation.Target; + (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitFunctionPointerWithArguments(target, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, operation.Type, IsImplicit(operation)); From 0273767474a6f6fa018170b4fa75541c1f9c69e5 Mon Sep 17 00:00:00 2001 From: bernd Date: Sat, 30 Oct 2021 09:49:58 +0200 Subject: [PATCH 23/43] inline VisitFunctionPointerWithArguments --- .../Operations/ControlFlowGraphBuilder.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 41dcc786a4051..7c53bf0df055e 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5657,27 +5657,25 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? operation.Type, IsImplicit(operation)); } - private (IOperation? visitedInstance, ImmutableArray visitedArguments) VisitFunctionPointerWithArguments(IOperation? instance, ImmutableArray arguments) - { - if (instance != null) - { - PushOperand(VisitRequired(instance)); - } - - ImmutableArray visitedArguments = VisitArguments(arguments); - IOperation? visitedInstance = instance == null ? null : PopOperand(); - - return (visitedInstance, visitedArguments); - } - public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); IOperation? target = operation.Target; - (IOperation? visitedPointer, ImmutableArray visitedArguments) = VisitFunctionPointerWithArguments(target, operation.Arguments); + (IOperation? visitedPointer, ImmutableArray visitedArguments) = handlePointerAndArguments(target, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, operation.Type, IsImplicit(operation)); + + (IOperation? visitedInstance, ImmutableArray visitedArguments) handlePointerAndArguments(IOperation instance, + ImmutableArray arguments) + { + PushOperand(VisitRequired(instance)); + + ImmutableArray visitedArguments = VisitArguments(arguments); + IOperation? visitedInstance = PopOperand(); + + return (visitedInstance, visitedArguments); + } } private (IOperation? visitedInstance, ImmutableArray visitedArguments) VisitInstanceWithArguments(IOperation? instance, ImmutableArray arguments) From 150bc5e1f8df274b688c1feab494a4427262635d Mon Sep 17 00:00:00 2001 From: bernd Date: Sat, 30 Oct 2021 09:52:13 +0200 Subject: [PATCH 24/43] Equal -> Same --- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 0c4100cf39e73..41679e7b875ee 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -511,7 +511,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp var signature = operation.GetFunctionPointerSignature(); Assert.NotNull(signature); - Assert.Equal(((IFunctionPointerTypeSymbol)operation.Target.Type!).Signature, signature); + Assert.Same(((IFunctionPointerTypeSymbol)operation.Target.Type!).Signature, signature); AssertEx.Equal(children, operation.Children); } From c56677f28893984a0986292a467f2d0382e0bd16 Mon Sep 17 00:00:00 2001 From: bernd Date: Sat, 30 Oct 2021 16:24:08 +0200 Subject: [PATCH 25/43] return null if type is null --- src/Compilers/Core/Portable/Operations/OperationExtensions.cs | 4 ++-- src/Compilers/Core/Portable/PublicAPI.Unshipped.txt | 2 +- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs index 766431c4a3d17..6e2a5ce8f9447 100644 --- a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs +++ b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs @@ -17,9 +17,9 @@ public static partial class OperationExtensions /// /// Helper function to simplify the access to the function pointer signature of an FunctionPointerInvocationOperation /// - public static IMethodSymbol GetFunctionPointerSignature(this IFunctionPointerInvocationOperation functionPointer) + public static IMethodSymbol? GetFunctionPointerSignature(this IFunctionPointerInvocationOperation functionPointer) { - return ((IFunctionPointerTypeSymbol)functionPointer.Target.Type!).Signature; + return ((IFunctionPointerTypeSymbol?)functionPointer.Target.Type)?.Signature; } /// diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index e817d168f19cf..1194f2272e0fa 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -152,7 +152,7 @@ static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.SelectMany(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Func! predicate) -> Microsoft.CodeAnalysis.IncrementalValuesProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValueProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValueProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValuesProvider -static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature(this Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! functionPointer) -> Microsoft.CodeAnalysis.IMethodSymbol! +static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature(this Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! functionPointer) -> Microsoft.CodeAnalysis.IMethodSymbol? virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGenerators(string! language) -> System.Collections.Immutable.ImmutableArray virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray abstract Microsoft.CodeAnalysis.Compilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 41679e7b875ee..4fbb91febaaa8 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -510,8 +510,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp IEnumerable children = new[] { operation.Target }.Concat(operation.Arguments); var signature = operation.GetFunctionPointerSignature(); - Assert.NotNull(signature); - Assert.Same(((IFunctionPointerTypeSymbol)operation.Target.Type!).Signature, signature); + Assert.Same(((IFunctionPointerTypeSymbol?)operation.Target.Type)?.Signature, signature); AssertEx.Equal(children, operation.Children); } From 2e45411585933a96e33f943a92e307ca197d4e0a Mon Sep 17 00:00:00 2001 From: bernd Date: Sat, 30 Oct 2021 18:37:49 +0200 Subject: [PATCH 26/43] nullable annotation removed --- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 4fbb91febaaa8..72c6805942d20 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -510,7 +510,7 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp IEnumerable children = new[] { operation.Target }.Concat(operation.Arguments); var signature = operation.GetFunctionPointerSignature(); - Assert.Same(((IFunctionPointerTypeSymbol?)operation.Target.Type)?.Signature, signature); + Assert.Same(((IFunctionPointerTypeSymbol)operation.Target.Type)?.Signature, signature); AssertEx.Equal(children, operation.Children); } From b1c6724f987536a0c1cfb6ff3264e5b8cf433e4b Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 21:57:00 +0100 Subject: [PATCH 27/43] IOperation? -> IOperation --- .../Portable/Operations/ControlFlowGraphBuilder.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 7c53bf0df055e..eabfe4f35b2e1 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5660,19 +5660,19 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? public override IOperation? VisitFunctionPointerInvocation(IFunctionPointerInvocationOperation operation, int? argument) { EvalStackFrame frame = PushStackFrame(); - IOperation? target = operation.Target; - (IOperation? visitedPointer, ImmutableArray visitedArguments) = handlePointerAndArguments(target, operation.Arguments); + var target = operation.Target; + var (visitedPointer, visitedArguments) = handlePointerAndArguments(target, operation.Arguments); PopStackFrame(frame); return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, operation.Type, IsImplicit(operation)); - (IOperation? visitedInstance, ImmutableArray visitedArguments) handlePointerAndArguments(IOperation instance, - ImmutableArray arguments) + (IOperation visitedInstance, ImmutableArray visitedArguments) handlePointerAndArguments( + IOperation instance, ImmutableArray arguments) { PushOperand(VisitRequired(instance)); ImmutableArray visitedArguments = VisitArguments(arguments); - IOperation? visitedInstance = PopOperand(); + IOperation visitedInstance = PopOperand(); return (visitedInstance, visitedArguments); } From c49e938010befa0b8fe26390487282ef1c5d9c4c Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 22:23:58 +0100 Subject: [PATCH 28/43] Add `ITypeSymbol` for NoneOperation if available --- .../Portable/Operations/CSharpOperationFactory.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index a2450968ebe3b..2ec811899d3d2 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -314,10 +314,17 @@ public CSharpOperationFactory(SemanticModel semanticModel) break; } } - ImmutableArray children = GetIOperationChildren(boundNode); - return new NoneOperation(children, _semanticModel, boundNode.Syntax, type: null, constantValue, isImplicit: isImplicit); - + ITypeSymbol? type; + if (boundNode is BoundExpression boundExpr) + { + type = boundExpr.GetPublicTypeSymbol(); + } + else + { + type = null; + } + return new NoneOperation(children, _semanticModel, boundNode.Syntax, type: type, constantValue, isImplicit: isImplicit); default: // If you're hitting this because the IOperation test hook has failed, see // /docs/Compilers/IOperation Test Hook.md for instructions on how to fix. From 50bf09f99e9007a7b9319403cbb9ace08a01e0f9 Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 22:24:28 +0100 Subject: [PATCH 29/43] GetFunctionPointerSignature should return not null --- src/Compilers/Core/Portable/Operations/OperationExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs index 6e2a5ce8f9447..766431c4a3d17 100644 --- a/src/Compilers/Core/Portable/Operations/OperationExtensions.cs +++ b/src/Compilers/Core/Portable/Operations/OperationExtensions.cs @@ -17,9 +17,9 @@ public static partial class OperationExtensions /// /// Helper function to simplify the access to the function pointer signature of an FunctionPointerInvocationOperation /// - public static IMethodSymbol? GetFunctionPointerSignature(this IFunctionPointerInvocationOperation functionPointer) + public static IMethodSymbol GetFunctionPointerSignature(this IFunctionPointerInvocationOperation functionPointer) { - return ((IFunctionPointerTypeSymbol?)functionPointer.Target.Type)?.Signature; + return ((IFunctionPointerTypeSymbol)functionPointer.Target.Type!).Signature; } /// From 1d124b3d02f9649b0ab58f34dc7e8685e04a4cf2 Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 22:24:45 +0100 Subject: [PATCH 30/43] TestOperationVisitor check added --- src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs index 72c6805942d20..7909a9ef47bd6 100644 --- a/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs +++ b/src/Compilers/Test/Core/Compilation/TestOperationVisitor.cs @@ -510,7 +510,8 @@ public override void VisitFunctionPointerInvocation(IFunctionPointerInvocationOp IEnumerable children = new[] { operation.Target }.Concat(operation.Arguments); var signature = operation.GetFunctionPointerSignature(); - Assert.Same(((IFunctionPointerTypeSymbol)operation.Target.Type)?.Signature, signature); + Assert.NotNull(signature); + Assert.Same(((IFunctionPointerTypeSymbol)operation.Target.Type).Signature, signature); AssertEx.Equal(children, operation.Children); } From dc75c353bc084c52065579417321be22a55f417a Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 22:29:44 +0100 Subject: [PATCH 31/43] use switch expression --- .../Portable/Operations/CSharpOperationFactory.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 2ec811899d3d2..ec682017ee0d0 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -315,15 +315,11 @@ public CSharpOperationFactory(SemanticModel semanticModel) } } ImmutableArray children = GetIOperationChildren(boundNode); - ITypeSymbol? type; - if (boundNode is BoundExpression boundExpr) + ITypeSymbol? type = boundNode switch { - type = boundExpr.GetPublicTypeSymbol(); - } - else - { - type = null; - } + BoundExpression boundExpr => boundExpr.GetPublicTypeSymbol(), + _ => null + }; return new NoneOperation(children, _semanticModel, boundNode.Syntax, type: type, constantValue, isImplicit: isImplicit); default: // If you're hitting this because the IOperation test hook has failed, see From f0bca7eeb4ee4f34f66f90f3b852015bfca66072 Mon Sep 17 00:00:00 2001 From: bernd Date: Mon, 1 Nov 2021 22:46:46 +0100 Subject: [PATCH 32/43] API --- src/Compilers/Core/Portable/PublicAPI.Unshipped.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 1194f2272e0fa..e817d168f19cf 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -152,7 +152,7 @@ static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.SelectMany(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Func! predicate) -> Microsoft.CodeAnalysis.IncrementalValuesProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValueProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValueProvider static Microsoft.CodeAnalysis.IncrementalValueProviderExtensions.WithComparer(this Microsoft.CodeAnalysis.IncrementalValuesProvider source, System.Collections.Generic.IEqualityComparer! comparer) -> Microsoft.CodeAnalysis.IncrementalValuesProvider -static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature(this Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! functionPointer) -> Microsoft.CodeAnalysis.IMethodSymbol? +static Microsoft.CodeAnalysis.Operations.OperationExtensions.GetFunctionPointerSignature(this Microsoft.CodeAnalysis.Operations.IFunctionPointerInvocationOperation! functionPointer) -> Microsoft.CodeAnalysis.IMethodSymbol! virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGenerators(string! language) -> System.Collections.Immutable.ImmutableArray virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray abstract Microsoft.CodeAnalysis.Compilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray From 18393916ce443b7ed80ecbe9e7ea47243db13371 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 00:28:25 +0100 Subject: [PATCH 33/43] workaround: ignore type for tests --- .../Test/Core/Compilation/OperationTreeVerifier.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 0ec6f53389533..c5831e88224ef 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -97,7 +97,16 @@ private void LogCommonProperties(IOperation operation) // Type LogString(", "); - LogType(operation.Type); + if (operation.Kind == OperationKind.None) + { + //TODO: this should be removed! + //We need to update the tests to allow Types on NoneOperations + LogType(null); + } + else + { + LogType(operation.Type); + } // ConstantValue if (operation.ConstantValue.HasValue) From 17b09e0aac84b55e0a392ec37ed1870bac0846c3 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 00:34:06 +0100 Subject: [PATCH 34/43] test added --- .../IOperation/FunctionPointerOperations.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs index ca659f557be3f..fb7fa270de509 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/FunctionPointerOperations.cs @@ -211,6 +211,44 @@ void M(delegate* ptr) Assert.Equal(SpecialType.System_Void, signature.ReturnType.SpecialType); } + [Fact] + public void FunctionPointerUnsafe() + { + var comp = CreateFunctionPointerCompilation(@" +using System; +static unsafe class C +{ + static int Getter(int i) => i; + static void Print(delegate** p) + { + for (int i = 0; i < 3; i++) + Console.Write(/**/p[i](i)/**/); + } + + static void Main() + { + delegate** p = stackalloc delegate*[] { &Getter, &Getter, &Getter }; + Print(p); + } +} +"); + var expectedOperationTree = @" +IFunctionPointerInvocationOperation (OperationKind.FunctionPointerInvocation, Type: System.Int32) (Syntax: 'p[i](i)') + Target: + IOperation: (OperationKind.None, Type: null) (Syntax: 'p[i]') + Children(2): + IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: delegate**) (Syntax: 'p') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: ) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + "; + + VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics: new DiagnosticDescription[0]); + } + [Fact] public void FunctionPointerInvocation() { From 98e5c3745b2c5933fa7d5c0cb33a424df09843fb Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 08:50:45 +0100 Subject: [PATCH 35/43] condition for workaround extended --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index c5831e88224ef..133b22705f468 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -97,10 +97,10 @@ private void LogCommonProperties(IOperation operation) // Type LogString(", "); - if (operation.Kind == OperationKind.None) + if (operation.Kind == OperationKind.None && operation.Language == LanguageNames.CSharp && operation is NoneOperation) { //TODO: this should be removed! - //We need to update the tests to allow Types on NoneOperations + //We need to update the CSharp unit-tests to allow Types on NoneOperations LogType(null); } else From fdafc02436b95cfe0aef4a2c666b33e77b78663e Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 11:04:26 +0100 Subject: [PATCH 36/43] introduced WorkaroundNoneOperation --- .../Operations/CSharpOperationFactory.cs | 2 +- .../Portable/Operations/OperationNodes.cs | 23 ++++++++++++++++++- .../Core/Compilation/OperationTreeVerifier.cs | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index ec682017ee0d0..358c6b7bf2142 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -320,7 +320,7 @@ public CSharpOperationFactory(SemanticModel semanticModel) BoundExpression boundExpr => boundExpr.GetPublicTypeSymbol(), _ => null }; - return new NoneOperation(children, _semanticModel, boundNode.Syntax, type: type, constantValue, isImplicit: isImplicit); + return new WorkaroundNoneOperation(children, _semanticModel, boundNode.Syntax, type, constantValue, isImplicit); default: // If you're hitting this because the IOperation test hook has failed, see // /docs/Compilers/IOperation Test Hook.md for instructions on how to fix. diff --git a/src/Compilers/Core/Portable/Operations/OperationNodes.cs b/src/Compilers/Core/Portable/Operations/OperationNodes.cs index dab2d1375d057..d2eaf39e0d1eb 100644 --- a/src/Compilers/Core/Portable/Operations/OperationNodes.cs +++ b/src/Compilers/Core/Portable/Operations/OperationNodes.cs @@ -13,9 +13,30 @@ namespace Microsoft.CodeAnalysis.Operations /// /// Use this to create IOperation when we don't have proper specific IOperation yet for given language construct /// - internal sealed class NoneOperation : Operation + internal sealed class NoneOperation : AbstractNoneOperation { public NoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : + base(children, semanticModel, syntax, type, constantValue, isImplicit) + { + } + } + + /// + /// This is a class to support Types for NoneOperations without breaking all tests. + /// It's purpose is to allow special handling in OperationTreeVerifier. + /// This class should be removed soon - see CSharpOperationFactory.Create / OperationTreeVerifier.LogCommonProperties + /// + internal sealed class WorkaroundNoneOperation : AbstractNoneOperation + { + public WorkaroundNoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : + base(children, semanticModel, syntax, type, constantValue, isImplicit) + { + } + } + + internal abstract class AbstractNoneOperation : Operation + { + public AbstractNoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : base(semanticModel, syntax, isImplicit) { Children = SetParentOperation(children, this); diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 133b22705f468..1ddf5e53b462e 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -97,7 +97,7 @@ private void LogCommonProperties(IOperation operation) // Type LogString(", "); - if (operation.Kind == OperationKind.None && operation.Language == LanguageNames.CSharp && operation is NoneOperation) + if (operation.Kind == OperationKind.None && operation.Language == LanguageNames.CSharp && operation is WorkaroundNoneOperation) { //TODO: this should be removed! //We need to update the CSharp unit-tests to allow Types on NoneOperations From d076cce61b2aa049d852769dfcebab5fb9a3d173 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 12:09:13 +0100 Subject: [PATCH 37/43] adjusted CFG for workaround --- .../Portable/Operations/ControlFlowGraphBuilder.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index eabfe4f35b2e1..9a876e6c9e3c4 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -6337,8 +6337,17 @@ private IOperation VisitNoneOperationStatement(IOperation operation) private IOperation VisitNoneOperationExpression(IOperation operation) { - return PopStackFrame(PushStackFrame(), - new NoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation))); + IOperation newOp; + if (operation is WorkaroundNoneOperation) + { + newOp = new WorkaroundNoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation)); + } + else + { + newOp = new NoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation)); + } + + return PopStackFrame(PushStackFrame(), newOp); } public override IOperation? VisitInterpolatedStringHandlerCreation(IInterpolatedStringHandlerCreationOperation operation, int? captureIdForResult) From 8eb4e482bb9e29a7f9834703f7d25aeff0a19a43 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 23:37:37 +0100 Subject: [PATCH 38/43] Revert "workaround extended" This reverts commit 98e5c3745b2c5933fa7d5c0cb33a424df09843fb. --- .../Operations/CSharpOperationFactory.cs | 2 +- .../Operations/ControlFlowGraphBuilder.cs | 13 ++--------- .../Portable/Operations/OperationNodes.cs | 23 +------------------ .../Core/Compilation/OperationTreeVerifier.cs | 4 ++-- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 358c6b7bf2142..ec682017ee0d0 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -320,7 +320,7 @@ public CSharpOperationFactory(SemanticModel semanticModel) BoundExpression boundExpr => boundExpr.GetPublicTypeSymbol(), _ => null }; - return new WorkaroundNoneOperation(children, _semanticModel, boundNode.Syntax, type, constantValue, isImplicit); + return new NoneOperation(children, _semanticModel, boundNode.Syntax, type: type, constantValue, isImplicit: isImplicit); default: // If you're hitting this because the IOperation test hook has failed, see // /docs/Compilers/IOperation Test Hook.md for instructions on how to fix. diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 9a876e6c9e3c4..eabfe4f35b2e1 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -6337,17 +6337,8 @@ private IOperation VisitNoneOperationStatement(IOperation operation) private IOperation VisitNoneOperationExpression(IOperation operation) { - IOperation newOp; - if (operation is WorkaroundNoneOperation) - { - newOp = new WorkaroundNoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation)); - } - else - { - newOp = new NoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation)); - } - - return PopStackFrame(PushStackFrame(), newOp); + return PopStackFrame(PushStackFrame(), + new NoneOperation(VisitArray(((Operation)operation).ChildOperations.ToImmutableArray()), semanticModel: null, operation.Syntax, operation.Type, operation.GetConstantValue(), IsImplicit(operation))); } public override IOperation? VisitInterpolatedStringHandlerCreation(IInterpolatedStringHandlerCreationOperation operation, int? captureIdForResult) diff --git a/src/Compilers/Core/Portable/Operations/OperationNodes.cs b/src/Compilers/Core/Portable/Operations/OperationNodes.cs index d2eaf39e0d1eb..dab2d1375d057 100644 --- a/src/Compilers/Core/Portable/Operations/OperationNodes.cs +++ b/src/Compilers/Core/Portable/Operations/OperationNodes.cs @@ -13,30 +13,9 @@ namespace Microsoft.CodeAnalysis.Operations /// /// Use this to create IOperation when we don't have proper specific IOperation yet for given language construct /// - internal sealed class NoneOperation : AbstractNoneOperation + internal sealed class NoneOperation : Operation { public NoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : - base(children, semanticModel, syntax, type, constantValue, isImplicit) - { - } - } - - /// - /// This is a class to support Types for NoneOperations without breaking all tests. - /// It's purpose is to allow special handling in OperationTreeVerifier. - /// This class should be removed soon - see CSharpOperationFactory.Create / OperationTreeVerifier.LogCommonProperties - /// - internal sealed class WorkaroundNoneOperation : AbstractNoneOperation - { - public WorkaroundNoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : - base(children, semanticModel, syntax, type, constantValue, isImplicit) - { - } - } - - internal abstract class AbstractNoneOperation : Operation - { - public AbstractNoneOperation(ImmutableArray children, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit) : base(semanticModel, syntax, isImplicit) { Children = SetParentOperation(children, this); diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index 1ddf5e53b462e..c5831e88224ef 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -97,10 +97,10 @@ private void LogCommonProperties(IOperation operation) // Type LogString(", "); - if (operation.Kind == OperationKind.None && operation.Language == LanguageNames.CSharp && operation is WorkaroundNoneOperation) + if (operation.Kind == OperationKind.None) { //TODO: this should be removed! - //We need to update the CSharp unit-tests to allow Types on NoneOperations + //We need to update the tests to allow Types on NoneOperations LogType(null); } else From f9eebf06cbc1e3dc97dcc3329bbf16edc5a4a99b Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 23:48:58 +0100 Subject: [PATCH 39/43] OperationTreeVerifier check adjusted (OperationKind.None is not only used for NoneOperations) --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index c5831e88224ef..ba6252fb1883e 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -97,7 +97,7 @@ private void LogCommonProperties(IOperation operation) // Type LogString(", "); - if (operation.Kind == OperationKind.None) + if (operation.Language == LanguageNames.CSharp && operation is NoneOperation) { //TODO: this should be removed! //We need to update the tests to allow Types on NoneOperations From 4e731758e79823834ac5f7c5423a340f8bebfe4d Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 23:49:18 +0100 Subject: [PATCH 40/43] remove type in test --- .../IOperation/IOperationTests_IInterpolatedStringOperation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IInterpolatedStringOperation.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IInterpolatedStringOperation.cs index feb1d20c304d9..0d042f425e202 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IInterpolatedStringOperation.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IInterpolatedStringOperation.cs @@ -2308,7 +2308,7 @@ public CustomHandler(int literalLength, int formattedCount, C c, bool b, out boo InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: c) (OperationKind.Argument, Type: null) (Syntax: '$""literal{c,1:format}""') - IOperation: (OperationKind.None, Type: CustomHandler, IsImplicit) (Syntax: '$""literal{c,1:format}""') + IOperation: (OperationKind.None, Type: null, IsImplicit) (Syntax: '$""literal{c,1:format}""') Children(2): IObjectCreationOperation (Constructor: CustomHandler..ctor(System.Int32 literalLength, System.Int32 formattedCount, C c, System.Boolean b, out System.Boolean success)) (OperationKind.ObjectCreation, Type: CustomHandler, IsImplicit) (Syntax: '$""literal{c,1:format}""') Arguments(5): From 20edb231bd1ce7df8f5fa5b8616d190e888c2799 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 2 Nov 2021 23:54:10 +0100 Subject: [PATCH 41/43] issue linked --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index ba6252fb1883e..f902564f03e39 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -99,7 +99,7 @@ private void LogCommonProperties(IOperation operation) LogString(", "); if (operation.Language == LanguageNames.CSharp && operation is NoneOperation) { - //TODO: this should be removed! + //TODO: this should be removed! (see: https://github.com/dotnet/roslyn/issues/57531) //We need to update the tests to allow Types on NoneOperations LogType(null); } From 0d937d4f517b5ed0eb84123feefa29a2f102659d Mon Sep 17 00:00:00 2001 From: bernd Date: Wed, 3 Nov 2021 07:55:39 +0100 Subject: [PATCH 42/43] comment adjusted --- src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs index f902564f03e39..64c399e25f1fa 100644 --- a/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs +++ b/src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs @@ -99,8 +99,9 @@ private void LogCommonProperties(IOperation operation) LogString(", "); if (operation.Language == LanguageNames.CSharp && operation is NoneOperation) { - //TODO: this should be removed! (see: https://github.com/dotnet/roslyn/issues/57531) + //TODO: this should be removed! //We need to update the tests to allow Types on NoneOperations + //(see: https://github.com/dotnet/roslyn/issues/57531) LogType(null); } else From 9a0ec00d35c2c6a2c5302098b18b5f6ca9180142 Mon Sep 17 00:00:00 2001 From: bernd Date: Thu, 4 Nov 2021 22:55:36 +0100 Subject: [PATCH 43/43] suppression removed --- .../Core/Portable/Operations/ControlFlowGraphBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index eabfe4f35b2e1..8117eb2e18a1e 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -5663,7 +5663,7 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int? var target = operation.Target; var (visitedPointer, visitedArguments) = handlePointerAndArguments(target, operation.Arguments); PopStackFrame(frame); - return new FunctionPointerInvocationOperation(visitedPointer!, visitedArguments, semanticModel: null, operation.Syntax, + return new FunctionPointerInvocationOperation(visitedPointer, visitedArguments, semanticModel: null, operation.Syntax, operation.Type, IsImplicit(operation)); (IOperation visitedInstance, ImmutableArray visitedArguments) handlePointerAndArguments(