@@ -227,30 +227,76 @@ private static bool DoesMethodMatchUnsafeAccessorDeclaration(ref GenerationConte
227
227
// If we are, do it first.
228
228
if ( ! ignoreCustomModifiers )
229
229
{
230
- // Compare custom modifiers on the signatures.
231
- var declCustomMod = declSig . GetEmbeddedSignatureData ( EmbeddedSignatureDataKind . RequiredCustomModifier , EmbeddedSignatureDataKind . OptionalCustomModifier ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
232
- var maybeCustomMod = maybeSig . GetEmbeddedSignatureData ( EmbeddedSignatureDataKind . RequiredCustomModifier , EmbeddedSignatureDataKind . OptionalCustomModifier ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
233
- if ( ! CompareEmbeddedData ( context . Kind , declCustomMod , maybeCustomMod ) )
230
+ // Compare any unmanaged callconv and custom modifiers on the signatures.
231
+ // We treat unmanaged calling conventions at the same level of precedance
232
+ // as custom modifiers, eventhough they are normally bits in a signature.
233
+ ReadOnlySpan < EmbeddedSignatureDataKind > kinds = new EmbeddedSignatureDataKind [ ]
234
+ {
235
+ EmbeddedSignatureDataKind . UnmanagedCallConv ,
236
+ EmbeddedSignatureDataKind . RequiredCustomModifier ,
237
+ EmbeddedSignatureDataKind . OptionalCustomModifier
238
+ } ;
239
+
240
+ var declData = declSig . GetEmbeddedSignatureData ( kinds ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
241
+ var maybeData = maybeSig . GetEmbeddedSignatureData ( kinds ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
242
+ if ( declData . Length != maybeData . Length )
234
243
{
235
244
return false ;
236
245
}
246
+
247
+ // Validate the custom modifiers match precisely.
248
+ for ( int i = 0 ; i < declData . Length ; ++ i )
249
+ {
250
+ EmbeddedSignatureData dd = declData [ i ] ;
251
+ EmbeddedSignatureData md = maybeData [ i ] ;
252
+ if ( dd . kind != md . kind || dd . type != md . type )
253
+ {
254
+ return false ;
255
+ }
256
+
257
+ // The indices on non-constructor declarations require
258
+ // some slight modification since there is always an extra
259
+ // argument in the declaration compared to the target.
260
+ string declIndex = dd . index ;
261
+ if ( context . Kind != UnsafeAccessorKind . Constructor )
262
+ {
263
+ string unmanagedCallConvMaybe = string . Empty ;
264
+
265
+ // Check for and drop the unmanaged calling convention
266
+ // value suffix to add it back after updating below.
267
+ if ( declIndex . Contains ( '|' ) )
268
+ {
269
+ Debug . Assert ( dd . kind == EmbeddedSignatureDataKind . UnmanagedCallConv ) ;
270
+ var tmp = declIndex . Split ( '|' ) ;
271
+ Debug . Assert ( tmp . Length == 2 ) ;
272
+ declIndex = tmp [ 0 ] ;
273
+ unmanagedCallConvMaybe = "|" + tmp [ 1 ] ;
274
+ }
275
+
276
+ // Decrement the second to last index by one to
277
+ // account for the difference in declarations.
278
+ string [ ] lvls = declIndex . Split ( '.' ) ;
279
+ int toUpdate = lvls . Length < 2 ? 0 : lvls . Length - 2 ;
280
+ int idx = int . Parse ( lvls [ toUpdate ] , CultureInfo . InvariantCulture ) ;
281
+ idx -- ;
282
+ lvls [ toUpdate ] = idx . ToString ( ) ;
283
+ declIndex = string . Join ( "." , lvls ) + unmanagedCallConvMaybe ;
284
+ }
285
+
286
+ if ( declIndex != md . index )
287
+ {
288
+ return false ;
289
+ }
290
+ }
237
291
}
238
292
239
- // Validate calling convention.
293
+ // Validate calling convention of declaration .
240
294
if ( ( declSig . Flags & MethodSignatureFlags . UnmanagedCallingConventionMask )
241
295
!= ( maybeSig . Flags & MethodSignatureFlags . UnmanagedCallingConventionMask ) )
242
296
{
243
297
return false ;
244
298
}
245
299
246
- // Compare unmanaged callconv on the signatures.
247
- var declUnmanaged = declSig . GetEmbeddedSignatureData ( EmbeddedSignatureDataKind . UnmanagedCallConv ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
248
- var maybeUnmanaged = maybeSig . GetEmbeddedSignatureData ( EmbeddedSignatureDataKind . UnmanagedCallConv ) ?? Array . Empty < EmbeddedSignatureData > ( ) ;
249
- if ( ! CompareEmbeddedData ( context . Kind , declUnmanaged , maybeUnmanaged ) )
250
- {
251
- return false ;
252
- }
253
-
254
300
// Validate argument count and return type
255
301
if ( context . Kind == UnsafeAccessorKind . Constructor )
256
302
{
@@ -300,64 +346,6 @@ private static bool DoesMethodMatchUnsafeAccessorDeclaration(ref GenerationConte
300
346
}
301
347
302
348
return true ;
303
-
304
- static bool CompareEmbeddedData (
305
- UnsafeAccessorKind kind ,
306
- EmbeddedSignatureData [ ] declData ,
307
- EmbeddedSignatureData [ ] maybeData )
308
- {
309
- if ( declData . Length != maybeData . Length )
310
- {
311
- return false ;
312
- }
313
-
314
- // Validate the custom modifiers match precisely.
315
- for ( int i = 0 ; i < declData . Length ; ++ i )
316
- {
317
- EmbeddedSignatureData dd = declData [ i ] ;
318
- EmbeddedSignatureData md = maybeData [ i ] ;
319
- if ( dd . kind != md . kind || dd . type != md . type )
320
- {
321
- return false ;
322
- }
323
-
324
- // The indices on non-constructor declarations require
325
- // some slight modification since there is always an extra
326
- // argument in the declaration compared to the target.
327
- string declIndex = dd . index ;
328
- if ( kind != UnsafeAccessorKind . Constructor )
329
- {
330
- string unmanagedCallConvMaybe = string . Empty ;
331
-
332
- // Check for and drop the unmanaged calling convention
333
- // value suffix to add it back after updating below.
334
- if ( declIndex . Contains ( '|' ) )
335
- {
336
- Debug . Assert ( dd . kind == EmbeddedSignatureDataKind . UnmanagedCallConv ) ;
337
- var tmp = declIndex . Split ( '|' ) ;
338
- Debug . Assert ( tmp . Length == 2 ) ;
339
- declIndex = tmp [ 0 ] ;
340
- unmanagedCallConvMaybe = "|" + tmp [ 1 ] ;
341
- }
342
-
343
- // Decrement the second to last index by one to
344
- // account for the difference in declarations.
345
- string [ ] lvls = declIndex . Split ( '.' ) ;
346
- int toUpdate = lvls . Length < 2 ? 0 : lvls . Length - 2 ;
347
- int idx = int . Parse ( lvls [ toUpdate ] , CultureInfo . InvariantCulture ) ;
348
- idx -- ;
349
- lvls [ toUpdate ] = idx . ToString ( ) ;
350
- declIndex = string . Join ( "." , lvls ) + unmanagedCallConvMaybe ;
351
- }
352
-
353
- if ( declIndex != md . index )
354
- {
355
- return false ;
356
- }
357
- }
358
-
359
- return true ;
360
- }
361
349
}
362
350
363
351
private static bool TrySetTargetMethod ( ref GenerationContext context , string name , out bool isAmbiguous , bool ignoreCustomModifiers = true )
0 commit comments