@@ -3210,7 +3210,7 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN
32103210 }
32113211 else if ( ( namedDecl is FieldDecl fieldDecl ) && name . StartsWith ( "__AnonymousFieldDecl_" , StringComparison . Ordinal ) )
32123212 {
3213- if ( fieldDecl . Type . AsCXXRecordDecl ? . IsAnonymous == true )
3213+ if ( fieldDecl . Type . AsCXXRecordDecl ? . IsAnonymousStructOrUnion == true )
32143214 {
32153215 // For fields of anonymous types, use the name of the type but clean off the type
32163216 // kind tag at the end.
@@ -3242,12 +3242,72 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN
32423242 return remappedName ;
32433243 }
32443244
3245+ private static int GetAnonymousRecordIndex ( RecordDecl recordDecl , RecordDecl parentRecordDecl )
3246+ {
3247+ var index = - 1 ;
3248+ var parentAnonRecordCount = parentRecordDecl . AnonymousRecords . Count ;
3249+
3250+ if ( parentAnonRecordCount != 0 )
3251+ {
3252+ index = parentRecordDecl . AnonymousRecords . IndexOf ( recordDecl ) ;
3253+
3254+ if ( index != - 1 )
3255+ {
3256+ if ( parentAnonRecordCount > 1 )
3257+ {
3258+ index ++ ;
3259+ }
3260+
3261+ if ( parentRecordDecl . Parent is RecordDecl grandParentRecordDecl )
3262+ {
3263+ var parentIndex = GetAnonymousRecordIndex ( parentRecordDecl , grandParentRecordDecl ) ;
3264+
3265+ // We can't have the nested anonymous record have the same name as the parent
3266+ // so skip that index and just go one higher instead. This could still conflict
3267+ // with another anonymous record at a different level, but that is less likely
3268+ // and will still be unambiguous in total.
3269+
3270+ if ( parentIndex == index )
3271+ {
3272+ if ( recordDecl . IsUnion == parentRecordDecl . IsUnion )
3273+ {
3274+ index ++ ;
3275+ }
3276+ }
3277+ else if ( ( parentIndex != 0 ) && ( index > parentIndex ) )
3278+ {
3279+ if ( recordDecl . IsUnion == parentRecordDecl . AnonymousRecords [ parentIndex ] . IsUnion )
3280+ {
3281+ index ++ ;
3282+ }
3283+ }
3284+ }
3285+ }
3286+ }
3287+
3288+ return index ;
3289+ }
3290+
32453291 private string GetRemappedNameForAnonymousRecord ( RecordDecl recordDecl )
32463292 {
32473293 if ( recordDecl . Parent is RecordDecl parentRecordDecl )
32483294 {
32493295 var remappedNameBuilder = new StringBuilder ( ) ;
3250- var matchingField = parentRecordDecl . Fields . Where ( ( fieldDecl ) => fieldDecl . Type . CanonicalType == recordDecl . TypeForDecl . CanonicalType ) . FirstOrDefault ( ) ;
3296+ var matchingField = null as FieldDecl ;
3297+
3298+ if ( ! recordDecl . IsAnonymousStructOrUnion )
3299+ {
3300+ matchingField = parentRecordDecl . Fields . Where ( ( fieldDecl ) => {
3301+ var fieldType = fieldDecl . Type . CanonicalType ;
3302+
3303+ if ( fieldType is ArrayType arrayType )
3304+ {
3305+ fieldType = arrayType . ElementType . CanonicalType ;
3306+ }
3307+
3308+ return fieldType == recordDecl . TypeForDecl . CanonicalType ;
3309+ } ) . FirstOrDefault ( ) ;
3310+ }
32513311
32523312 if ( ( matchingField is not null ) && ! matchingField . IsAnonymousField )
32533313 {
@@ -3258,28 +3318,11 @@ private string GetRemappedNameForAnonymousRecord(RecordDecl recordDecl)
32583318 {
32593319 _ = remappedNameBuilder . Append ( "_Anonymous" ) ;
32603320
3261- // If there is more than one anonymous type, then add a numeral to differentiate.
3262- if ( parentRecordDecl . AnonymousRecords . Count > 1 )
3263- {
3264- var index = parentRecordDecl . AnonymousRecords . IndexOf ( recordDecl ) + 1 ;
3265- Debug . Assert ( index > 0 ) ;
3266- _ = remappedNameBuilder . Append ( index ) ;
3267- }
3321+ var index = GetAnonymousRecordIndex ( recordDecl , parentRecordDecl ) ;
32683322
3269- // C# doesn't allow a nested type to have the same name as the parent, so if the
3270- // parent is also anonymous, add the nesting depth as a way to avoid conflicts with
3271- // the parent's name.
3272- if ( parentRecordDecl . IsAnonymous )
3323+ if ( index != 0 )
32733324 {
3274- var depth = 1 ;
3275- var currentParent = parentRecordDecl . Parent ;
3276- while ( ( currentParent is RecordDecl currentParentRecordDecl ) && currentParentRecordDecl . IsAnonymous )
3277- {
3278- depth ++ ;
3279- currentParent = currentParentRecordDecl . Parent ;
3280- }
3281- _ = remappedNameBuilder . Append ( '_' ) ;
3282- _ = remappedNameBuilder . Append ( depth ) ;
3325+ _ = remappedNameBuilder . Append ( index ) ;
32833326 }
32843327 }
32853328
@@ -4625,7 +4668,7 @@ private bool HasBaseField(CXXRecordDecl cxxRecordDecl)
46254668
46264669 private bool HasField ( RecordDecl recordDecl )
46274670 {
4628- var hasField = recordDecl . Fields . Any ( ) || recordDecl . Decls . Any ( ( decl ) => ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymous && HasField ( nestedRecordDecl ) ) ;
4671+ var hasField = recordDecl . Fields . Any ( ) || recordDecl . Decls . Any ( ( decl ) => ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymousStructOrUnion && HasField ( nestedRecordDecl ) ) ;
46294672
46304673 if ( ! hasField && ( recordDecl is CXXRecordDecl cxxRecordDecl ) )
46314674 {
@@ -5170,7 +5213,7 @@ bool IsEmptyRecord(RecordDecl recordDecl)
51705213
51715214 foreach ( var decl in recordDecl . Decls )
51725215 {
5173- if ( ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymous && ! IsEmptyRecord ( nestedRecordDecl ) )
5216+ if ( ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymousStructOrUnion && ! IsEmptyRecord ( nestedRecordDecl ) )
51745217 {
51755218 return false ;
51765219 }
@@ -6195,7 +6238,7 @@ private bool IsUnsafe(RecordDecl recordDecl)
61956238 {
61966239 return true ;
61976240 }
6198- else if ( ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymous && ( IsUnsafe ( nestedRecordDecl ) || Config . GenerateCompatibleCode ) )
6241+ else if ( ( decl is RecordDecl nestedRecordDecl ) && nestedRecordDecl . IsAnonymousStructOrUnion && ( IsUnsafe ( nestedRecordDecl ) || Config . GenerateCompatibleCode ) )
61996242 {
62006243 return true ;
62016244 }
0 commit comments