Skip to content

Commit b4aff2b

Browse files
Merge pull request #373 from tannergooding/main
Ensure that multiple-inheritance scenarios generate unique field names
2 parents 99ab606 + 1fbe370 commit b4aff2b

File tree

11 files changed

+72
-46
lines changed

11 files changed

+72
-46
lines changed

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
597597

598598
_outputBuilder.BeginFunctionInnerPrototype(in desc);
599599

600-
bool needsThis = isVirtual || (isCxxMethodDecl && !hasBody && cxxMethodDecl.IsInstance);
600+
var needsThis = isVirtual || (isCxxMethodDecl && !hasBody && cxxMethodDecl.IsInstance);
601601

602602
if (needsThis)
603603
{
@@ -669,7 +669,12 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
669669
outputBuilder.Write("return ");
670670
}
671671

672-
outputBuilder.Write("Base.");
672+
var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).Single();
673+
var baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base");
674+
baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true);
675+
676+
outputBuilder.Write(baseFieldName);
677+
outputBuilder.Write('.');
673678
outputBuilder.Write(name);
674679
outputBuilder.Write('(');
675680

@@ -1564,8 +1569,9 @@ private void VisitRecordDecl(RecordDecl recordDecl)
15641569

15651570
if (cxxRecordDecl != null)
15661571
{
1567-
foreach (var cxxBaseSpecifier in cxxRecordDecl.Bases)
1572+
for (var index = 0; index < cxxRecordDecl.Bases.Count; index++)
15681573
{
1574+
var cxxBaseSpecifier = cxxRecordDecl.Bases[index];
15691575
var baseCxxRecordDecl = GetRecordDecl(cxxBaseSpecifier);
15701576

15711577
if (HasField(baseCxxRecordDecl))
@@ -1574,11 +1580,6 @@ private void VisitRecordDecl(RecordDecl recordDecl)
15741580
var baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base");
15751581
baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true);
15761582

1577-
if (baseFieldName.StartsWith("__AnonymousBase_"))
1578-
{
1579-
baseFieldName = "Base";
1580-
}
1581-
15821583
var fieldDesc = new FieldDesc {
15831584
AccessSpecifier = GetAccessSpecifier(baseCxxRecordDecl, matchStar: true),
15841585
NativeTypeName = null,

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,27 +1597,37 @@ private void VisitLabelStmt(LabelStmt labelStmt)
15971597
private void VisitMemberExpr(MemberExpr memberExpr)
15981598
{
15991599
var outputBuilder = StartCSharpCode();
1600-
var isForDerivedType = false;
1600+
var baseFieldName = "";
16011601

16021602
if ((memberExpr.Base is ImplicitCastExpr implicitCastExpr) && (implicitCastExpr.CastKind is CX_CastKind.CX_CK_DerivedToBase or CX_CastKind.CX_CK_DerivedToBaseMemberPointer or CX_CastKind.CX_CK_UncheckedDerivedToBase))
16031603
{
16041604
if (memberExpr.MemberDecl is CXXMethodDecl cxxMethodDecl)
16051605
{
1606-
isForDerivedType = (_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != cxxMethodDecl.Parent) && HasField(cxxMethodDecl.Parent);
1606+
if ((_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != cxxMethodDecl.Parent) && HasField(cxxMethodDecl.Parent))
1607+
{
1608+
var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).Single();
1609+
baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base");
1610+
baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true);
1611+
}
16071612
}
16081613
else if (memberExpr.MemberDecl is FieldDecl fieldDecl)
16091614
{
1610-
isForDerivedType = (_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != fieldDecl.Parent);
1615+
if ((_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != fieldDecl.Parent))
1616+
{
1617+
var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == fieldDecl.Parent).Single();
1618+
baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base");
1619+
baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true);
1620+
}
16111621
}
16121622
}
16131623

1614-
if (!memberExpr.IsImplicitAccess || isForDerivedType)
1624+
if (!memberExpr.IsImplicitAccess || !string.IsNullOrWhiteSpace(baseFieldName))
16151625
{
16161626
var memberExprBase = memberExpr.Base.IgnoreImplicit;
16171627

1618-
if (isForDerivedType)
1628+
if (!string.IsNullOrWhiteSpace(baseFieldName))
16191629
{
1620-
outputBuilder.Write("Base");
1630+
outputBuilder.Write(baseFieldName);
16211631
}
16221632
else
16231633
{

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.IO;
77
using System.Linq;
8+
using System.Reflection;
89
using System.Runtime.InteropServices;
910
using System.Text;
1011
using System.Text.RegularExpressions;
@@ -2503,6 +2504,20 @@ private string GetRemappedName(string name, Cursor cursor, bool tryRemapOperator
25032504
return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing);
25042505
}
25052506

2507+
if ((cursor is CXXBaseSpecifier cxxBaseSpecifier) && remappedName.StartsWith("__AnonymousBase_"))
2508+
{
2509+
remappedName = "Base";
2510+
2511+
if (_cxxRecordDeclContext.Bases.Count > 1)
2512+
{
2513+
var index = _cxxRecordDeclContext.Bases.IndexOf(cxxBaseSpecifier) + 1;
2514+
remappedName += index.ToString();
2515+
}
2516+
2517+
wasRemapped = true;
2518+
return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing);
2519+
}
2520+
25062521
wasRemapped = false;
25072522
return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsingIfNotRemapped);
25082523

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,9 +755,9 @@ public partial struct MyStruct1B
755755
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
756756
public partial struct MyStruct2
757757
{
758-
public MyStruct1A Base;
758+
public MyStruct1A Base1;
759759
760-
public MyStruct1B Base;
760+
public MyStruct1B Base2;
761761
762762
public int z;
763763
@@ -810,9 +810,9 @@ public partial struct MyStruct1B
810810
[NativeInheritance(""MyStruct1B"")]
811811
public partial struct MyStruct2
812812
{
813-
public MyStruct1A Base;
813+
public MyStruct1A Base1;
814814
815-
public MyStruct1B Base;
815+
public MyStruct1B Base2;
816816
817817
public int z;
818818

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,9 @@ public partial struct MyStruct1B
759759
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
760760
public partial struct MyStruct2
761761
{
762-
public MyStruct1A Base;
762+
public MyStruct1A Base1;
763763
764-
public MyStruct1B Base;
764+
public MyStruct1B Base2;
765765
766766
public int z;
767767
@@ -814,9 +814,9 @@ public partial struct MyStruct1B
814814
[NativeInheritance(""MyStruct1B"")]
815815
public partial struct MyStruct2
816816
{
817-
public MyStruct1A Base;
817+
public MyStruct1A Base1;
818818
819-
public MyStruct1B Base;
819+
public MyStruct1B Base2;
820820
821821
public int z;
822822

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -763,9 +763,9 @@ public partial struct MyStruct1B
763763
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
764764
public partial struct MyStruct2
765765
{
766-
public MyStruct1A Base;
766+
public MyStruct1A Base1;
767767
768-
public MyStruct1B Base;
768+
public MyStruct1B Base2;
769769
770770
public int z;
771771
@@ -818,9 +818,9 @@ public partial struct MyStruct1B
818818
[NativeInheritance(""MyStruct1B"")]
819819
public partial struct MyStruct2
820820
{
821-
public MyStruct1A Base;
821+
public MyStruct1A Base1;
822822
823-
public MyStruct1B Base;
823+
public MyStruct1B Base2;
824824
825825
public int z;
826826

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -767,9 +767,9 @@ public partial struct MyStruct1B
767767
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
768768
public partial struct MyStruct2
769769
{
770-
public MyStruct1A Base;
770+
public MyStruct1A Base1;
771771
772-
public MyStruct1B Base;
772+
public MyStruct1B Base2;
773773
774774
public int z;
775775
@@ -822,9 +822,9 @@ public partial struct MyStruct1B
822822
[NativeInheritance(""MyStruct1B"")]
823823
public partial struct MyStruct2
824824
{
825-
public MyStruct1A Base;
825+
public MyStruct1A Base1;
826826
827-
public MyStruct1B Base;
827+
public MyStruct1B Base2;
828828
829829
public int z;
830830

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -798,10 +798,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
798798
</field>
799799
</struct>
800800
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"">
801-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
801+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
802802
<type>MyStruct1A</type>
803803
</field>
804-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
804+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
805805
<type>MyStruct1B</type>
806806
</field>
807807
<field name=""z"" access=""public"">
@@ -859,10 +859,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
859859
</field>
860860
</struct>
861861
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"" parent=""MyStruct1B"">
862-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
862+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
863863
<type>MyStruct1A</type>
864864
</field>
865-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
865+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
866866
<type>MyStruct1B</type>
867867
</field>
868868
<field name=""z"" access=""public"">

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -804,10 +804,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
804804
</field>
805805
</struct>
806806
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"">
807-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
807+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
808808
<type>MyStruct1A</type>
809809
</field>
810-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
810+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
811811
<type>MyStruct1B</type>
812812
</field>
813813
<field name=""z"" access=""public"">
@@ -865,10 +865,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
865865
</field>
866866
</struct>
867867
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"" parent=""MyStruct1B"">
868-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
868+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
869869
<type>MyStruct1A</type>
870870
</field>
871-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
871+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
872872
<type>MyStruct1B</type>
873873
</field>
874874
<field name=""z"" access=""public"">

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
802802
</field>
803803
</struct>
804804
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"">
805-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
805+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
806806
<type>MyStruct1A</type>
807807
</field>
808-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
808+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
809809
<type>MyStruct1B</type>
810810
</field>
811811
<field name=""z"" access=""public"">
@@ -863,10 +863,10 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
863863
</field>
864864
</struct>
865865
<struct name=""MyStruct2"" access=""public"" native=""struct MyStruct2 : MyStruct1A, MyStruct1B"" parent=""MyStruct1B"">
866-
<field name=""Base"" access=""public"" inherited=""MyStruct1A"">
866+
<field name=""Base1"" access=""public"" inherited=""MyStruct1A"">
867867
<type>MyStruct1A</type>
868868
</field>
869-
<field name=""Base"" access=""public"" inherited=""MyStruct1B"">
869+
<field name=""Base2"" access=""public"" inherited=""MyStruct1B"">
870870
<type>MyStruct1B</type>
871871
</field>
872872
<field name=""z"" access=""public"">

0 commit comments

Comments
 (0)