Skip to content

Commit caed19e

Browse files
committed
Generate valid C# when a secondary base has a public anonymous field
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 2919dfd commit caed19e

File tree

4 files changed

+41
-11
lines changed

4 files changed

+41
-11
lines changed

src/Generator/Driver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ public void SetupPasses(ILibrary library)
246246

247247
Generator.SetupPasses();
248248

249-
TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass());
250249
TranslationUnitPasses.AddPass(new FlattenAnonymousTypesToFields());
250+
TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass());
251251
TranslationUnitPasses.AddPass(new FieldToPropertyPass());
252252
TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
253253
TranslationUnitPasses.AddPass(new CheckFlagEnumsPass());

src/Generator/Passes/FlattenAnonymousTypesToFields.cs

+30-9
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,23 @@ public override bool VisitClassDecl(Class @class)
4343
continue;
4444

4545
ReplaceField(@class, i, fieldType);
46-
ReplaceLayoutField(@class, field, fieldType);
46+
fieldType.Fields.Clear();
47+
fieldType.ExplicitlyIgnore();
48+
}
49+
50+
if (@class.Layout == null)
51+
return true;
52+
53+
for (int i = @class.Layout.Fields.Count - 1; i >= 0; i--)
54+
{
55+
LayoutField field = @class.Layout.Fields[i];
56+
Class fieldType;
57+
if (!string.IsNullOrEmpty(field.Name) ||
58+
!field.QualifiedType.Type.Desugar().TryGetClass(out fieldType) ||
59+
!string.IsNullOrEmpty(fieldType.OriginalName))
60+
continue;
61+
62+
ReplaceLayoutField(@class, i, fieldType);
4763
fieldType.Fields.Clear();
4864
fieldType.ExplicitlyIgnore();
4965
}
@@ -63,18 +79,23 @@ private static void ReplaceField(Class @class, int i, Class fieldType)
6379
}
6480
}
6581

66-
private static void ReplaceLayoutField(Class @class, Field field, Class fieldType)
82+
private static void ReplaceLayoutField(Class @class, int i, Class fieldType)
6783
{
68-
LayoutField layoutField = @class.Layout.Fields.Find(
69-
f => f.FieldPtr == field.OriginalPtr);
70-
int layoutIndex = @class.Layout.Fields.IndexOf(layoutField);
71-
@class.Layout.Fields.RemoveAt(layoutIndex);
84+
uint offset = @class.Layout.Fields[i].Offset;
85+
@class.Layout.Fields.RemoveAt(i);
7286

7387
for (int j = 0; j < fieldType.Layout.Fields.Count; j++)
7488
{
75-
LayoutField nestedlayoutField = fieldType.Layout.Fields[j];
76-
nestedlayoutField.Offset += layoutField.Offset;
77-
@class.Layout.Fields.Insert(layoutIndex + j, nestedlayoutField);
89+
LayoutField nestedLayoutField = fieldType.Layout.Fields[j];
90+
var layoutField = new LayoutField
91+
{
92+
Expression = nestedLayoutField.Expression,
93+
FieldPtr = nestedLayoutField.FieldPtr,
94+
Name = nestedLayoutField.Name,
95+
Offset = nestedLayoutField.Offset + offset,
96+
QualifiedType = nestedLayoutField.QualifiedType
97+
};
98+
@class.Layout.Fields.Insert(i + j, layoutField);
7899
}
79100
}
80101
}

tests/CSharp/CSharp.Tests.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ public void TestMultipleInheritance()
142142
Assert.That(baz.TakesQux(baz), Is.EqualTo(20));
143143
Assert.That(baz.ReturnQux().FarAwayFunc, Is.EqualTo(20));
144144
baz.SetMethod(1);
145-
Assert.AreEqual(5, baz.P);
145+
Assert.That(baz.P, Is.EqualTo(5));
146+
baz.PublicDouble = 1.5;
147+
Assert.That(baz.PublicDouble, Is.EqualTo(1.5));
148+
baz.PublicInt = 15;
149+
Assert.That(baz.PublicInt, Is.EqualTo(15));
146150
}
147151
}
148152

tests/CSharp/CSharp.h

+5
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ class DLL_API Bar : public Qux
104104
Foo foos[4];
105105
int getIndex();
106106
void setIndex(int value);
107+
union
108+
{
109+
int publicInt;
110+
double publicDouble;
111+
};
107112

108113
private:
109114
int index;

0 commit comments

Comments
 (0)