Skip to content

Commit 7952df7

Browse files
authored
Ensure that we don't root the compilation when using a custom exception marshalling type. (#80147)
1 parent 02681cd commit 7952df7

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,36 @@
66
namespace Microsoft.Interop
77
{
88
/// <summary>
9-
/// VirtualMethodIndexAttribute data
9+
/// Contains the data related to a VirtualMethodIndexAttribute, without references to Roslyn symbols.
10+
/// See <seealso cref="VirtualMethodIndexCompilationData"/> for a type with a reference to the StringMarshallingCustomType
1011
/// </summary>
11-
internal sealed record VirtualMethodIndexData(int Index) : InteropAttributeCompilationData
12+
internal sealed record VirtualMethodIndexData(
13+
int Index,
14+
bool ImplicitThisParameter,
15+
MarshalDirection Direction,
16+
bool ExceptionMarshallingDefined,
17+
ExceptionMarshalling ExceptionMarshalling) : InteropAttributeData
18+
{
19+
20+
public static VirtualMethodIndexData From(VirtualMethodIndexCompilationData virtualMethodIndex)
21+
=> new VirtualMethodIndexData(
22+
virtualMethodIndex.Index,
23+
virtualMethodIndex.ImplicitThisParameter,
24+
virtualMethodIndex.Direction,
25+
virtualMethodIndex.ExceptionMarshallingDefined,
26+
virtualMethodIndex.ExceptionMarshalling)
27+
{
28+
IsUserDefined = virtualMethodIndex.IsUserDefined,
29+
SetLastError = virtualMethodIndex.SetLastError,
30+
StringMarshalling = virtualMethodIndex.StringMarshalling
31+
};
32+
}
33+
34+
/// <summary>
35+
/// Contains the data related to a VirtualMethodIndexAttribute, with references to Roslyn symbols.
36+
/// Use <seealso cref="VirtualMethodIndexData"/> instead when using for incremental compilation state to avoid keeping a compilation alive
37+
/// </summary>
38+
internal sealed record VirtualMethodIndexCompilationData(int Index) : InteropAttributeCompilationData
1239
{
1340
public bool ImplicitThisParameter { get; init; }
1441

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
193193
.WithBody(stubCode);
194194
}
195195

196-
private static VirtualMethodIndexData? ProcessVirtualMethodIndexAttribute(AttributeData attrData)
196+
private static VirtualMethodIndexCompilationData? ProcessVirtualMethodIndexAttribute(AttributeData attrData)
197197
{
198198
// Found the attribute, but it has an error so report the error.
199199
// This is most likely an issue with targeting an incorrect TFM.
@@ -214,7 +214,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
214214
bool exceptionMarshallingDefined = false;
215215
ExceptionMarshalling exceptionMarshalling = ExceptionMarshalling.Custom;
216216
INamedTypeSymbol? exceptionMarshallingCustomType = null;
217-
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.Direction), out TypedConstant directionValue))
217+
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.Direction), out TypedConstant directionValue))
218218
{
219219
// TypedConstant's Value property only contains primitive values.
220220
if (directionValue.Value is not int)
@@ -224,15 +224,15 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
224224
// A boxed primitive can be unboxed to an enum with the same underlying type.
225225
direction = (MarshalDirection)directionValue.Value!;
226226
}
227-
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ImplicitThisParameter), out TypedConstant implicitThisValue))
227+
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ImplicitThisParameter), out TypedConstant implicitThisValue))
228228
{
229229
if (implicitThisValue.Value is not bool)
230230
{
231231
return null;
232232
}
233233
implicitThis = (bool)implicitThisValue.Value!;
234234
}
235-
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ExceptionMarshalling), out TypedConstant exceptionMarshallingValue))
235+
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ExceptionMarshalling), out TypedConstant exceptionMarshallingValue))
236236
{
237237
exceptionMarshallingDefined = true;
238238
// TypedConstant's Value property only contains primitive values.
@@ -243,7 +243,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
243243
// A boxed primitive can be unboxed to an enum with the same underlying type.
244244
exceptionMarshalling = (ExceptionMarshalling)exceptionMarshallingValue.Value!;
245245
}
246-
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ExceptionMarshallingCustomType), out TypedConstant exceptionMarshallingCustomTypeValue))
246+
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ExceptionMarshallingCustomType), out TypedConstant exceptionMarshallingCustomTypeValue))
247247
{
248248
if (exceptionMarshallingCustomTypeValue.Value is not INamedTypeSymbol)
249249
{
@@ -252,7 +252,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
252252
exceptionMarshallingCustomType = (INamedTypeSymbol)exceptionMarshallingCustomTypeValue.Value;
253253
}
254254

255-
return new VirtualMethodIndexData((int)attrData.ConstructorArguments[0].Value).WithValuesFromNamedArguments(namedArguments) with
255+
return new VirtualMethodIndexCompilationData((int)attrData.ConstructorArguments[0].Value).WithValuesFromNamedArguments(namedArguments) with
256256
{
257257
Direction = direction,
258258
ImplicitThisParameter = implicitThis,
@@ -300,11 +300,11 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
300300
var generatorDiagnostics = new GeneratorDiagnostics();
301301

302302
// Process the LibraryImport attribute
303-
VirtualMethodIndexData? virtualMethodIndexData = ProcessVirtualMethodIndexAttribute(virtualMethodIndexAttr!);
303+
VirtualMethodIndexCompilationData? virtualMethodIndexData = ProcessVirtualMethodIndexAttribute(virtualMethodIndexAttr!);
304304

305305
if (virtualMethodIndexData is null)
306306
{
307-
virtualMethodIndexData = new VirtualMethodIndexData(-1);
307+
virtualMethodIndexData = new VirtualMethodIndexCompilationData(-1);
308308
}
309309
else if (virtualMethodIndexData.Index < 0)
310310
{
@@ -371,7 +371,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
371371
methodSyntaxTemplate,
372372
new MethodSignatureDiagnosticLocations(syntax),
373373
new SequenceEqualImmutableArray<FunctionPointerUnmanagedCallingConventionSyntax>(callConv, SyntaxEquivalentComparer.Instance),
374-
virtualMethodIndexData,
374+
VirtualMethodIndexData.From(virtualMethodIndexData),
375375
exceptionMarshallingInfo,
376376
ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.ManagedToUnmanaged),
377377
ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.UnmanagedToManaged),
@@ -380,7 +380,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
380380
new SequenceEqualImmutableArray<Diagnostic>(generatorDiagnostics.Diagnostics.ToImmutableArray()));
381381
}
382382

383-
private static MarshallingInfo CreateExceptionMarshallingInfo(AttributeData virtualMethodIndexAttr, ISymbol symbol, Compilation compilation, GeneratorDiagnostics diagnostics, VirtualMethodIndexData virtualMethodIndexData)
383+
private static MarshallingInfo CreateExceptionMarshallingInfo(AttributeData virtualMethodIndexAttr, ISymbol symbol, Compilation compilation, GeneratorDiagnostics diagnostics, VirtualMethodIndexCompilationData virtualMethodIndexData)
384384
{
385385
if (virtualMethodIndexData.ExceptionMarshallingDefined)
386386
{

0 commit comments

Comments
 (0)