Skip to content

Commit 0ae25ee

Browse files
committed
CSharp: More default parameter fixes
- Expression generation for `ConstructorReference` now also recursively calls `VisitExpression` for the argument if only one argument is detected. This allows correct overload generation for functions taking a variable as the default parameter value. - Default parameters of pointer-to-enumeration types are now correctly generated similar to primitive types.
1 parent 1ce9cb7 commit 0ae25ee

File tree

6 files changed

+57
-8
lines changed

6 files changed

+57
-8
lines changed

src/AST/TypeExtensions.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,25 @@ public static bool IsPointerToPrimitiveType(this Type t, PrimitiveType primitive
9292
return ptr.Pointee.IsPrimitiveType(primitive);
9393
}
9494

95+
public static bool IsPointerToEnum(this Type t)
96+
{
97+
var ptr = t as PointerType;
98+
if (ptr == null)
99+
return false;
100+
return ptr.Pointee.IsEnumType();
101+
}
102+
103+
public static bool IsPointerToEnum(this Type t, out Enumeration @enum)
104+
{
105+
var ptr = t as PointerType;
106+
if (ptr == null)
107+
{
108+
@enum = null;
109+
return false;
110+
}
111+
return ptr.Pointee.TryGetEnum(out @enum);
112+
}
113+
95114
public static bool IsPointerTo<T>(this Type t, out T type) where T : Type
96115
{
97116
var pointee = t.GetPointee();

src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public string VisitExpression(ExpressionObsolete expr)
6868
case StatementClass.ConstructorReference:
6969
var constructorExpr = (CXXConstructExprObsolete)expr;
7070
if (constructorExpr.Arguments.Count == 1 &&
71-
constructorExpr.Arguments[0].Declaration is Enumeration.Item)
72-
return constructorExpr.Arguments[0].Declaration.Visit(typePrinter).Type;
71+
constructorExpr.Arguments[0].Class != StatementClass.Any)
72+
return VisitExpression(constructorExpr.Arguments[0]);
7373
goto default;
7474
default:
7575
return expr.String;

src/Generator/Generators/CSharp/CSharpSources.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,7 +2783,7 @@ private bool GenerateMethodBody(Class @class, Method method,
27832783

27842784
private string OverloadParamNameWithDefValue(Parameter p, ref int index)
27852785
{
2786-
return p.Type.IsPointerToPrimitiveType() && p.Usage == ParameterUsage.InOut && p.HasDefaultValue
2786+
return (p.Type.IsPointerToPrimitiveType() || p.Type.IsPointerToEnum()) && p.Usage == ParameterUsage.InOut && p.HasDefaultValue
27872787
? "ref param" + index++
27882788
: ExpressionPrinter.VisitParameter(p);
27892789
}
@@ -2802,13 +2802,15 @@ private void GenerateOverloadCall(Function function)
28022802
for (int i = 0, j = 0; i < function.Parameters.Count; i++)
28032803
{
28042804
var parameter = function.Parameters[i];
2805-
PrimitiveType primitiveType;
2805+
PrimitiveType primitiveType = PrimitiveType.Null;
2806+
Enumeration enumeration = null;
28062807
if (parameter.Kind == ParameterKind.Regular && parameter.Ignore &&
2807-
parameter.Type.IsPointerToPrimitiveType(out primitiveType) &&
2808+
(parameter.Type.IsPointerToPrimitiveType(out primitiveType) ||
2809+
parameter.Type.IsPointerToEnum(out enumeration)) &&
28082810
parameter.Usage == ParameterUsage.InOut && parameter.HasDefaultValue)
28092811
{
28102812
var pointeeType = ((PointerType)parameter.Type).Pointee.ToString();
2811-
WriteLine($@"{pointeeType} param{j++} = {(primitiveType == PrimitiveType.Bool ? "false" : "0")};");
2813+
WriteLine($@"{pointeeType} param{j++} = {(primitiveType == PrimitiveType.Bool ? "false" : $"({pointeeType})0")};");
28122814
}
28132815
}
28142816

tests/dotnet/Common/Common.Tests.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ public void TestStdString()
929929
// when C++ memory is deleted, it's only marked as free but not immediadely freed
930930
// this can hide memory bugs while marshalling
931931
// so let's use a long string to increase the chance of a crash right away
932-
const string t = @"This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
932+
const string t = @"This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
933933
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
934934
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
935935
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
@@ -951,7 +951,7 @@ public void TestStdStringPassedByValue()
951951
// when C++ memory is deleted, it's only marked as free but not immediadely freed
952952
// this can hide memory bugs while marshalling
953953
// so let's use a long string to increase the chance of a crash right away
954-
const string t = @"This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
954+
const string t = @"This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
955955
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
956956
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
957957
This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string. This is a very long string.
@@ -1147,6 +1147,17 @@ public void TestReturnByValueWithReturnParam()
11471147
}
11481148
}
11491149

1150+
[Test]
1151+
public void TestDefaultParams()
1152+
{
1153+
Common.FunctionWithFlagsAsDefaultParameter();
1154+
Common.FunctionWithConstFlagsAsDefaultParameter();
1155+
Common.FunctionWithPointerToEnumAsDefaultParameter();
1156+
1157+
Assert.That(Common.FunctionWithNonPrimitiveAsDefaultParameter(),
1158+
Is.EqualTo(Common.FunctionWithNonPrimitiveAsDefaultParameter(Common.DefaultBar)));
1159+
}
1160+
11501161
[Test, Ignore("This was exposed by another bug and doesn't work yet.")]
11511162
public void TestFreeFunctionReturnByValue()
11521163
{

tests/dotnet/Common/Common.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,3 +1282,14 @@ void DLL_API FunctionWithFlagsAsDefaultParameter(int defaultParam)
12821282
void DLL_API FunctionWithConstFlagsAsDefaultParameter(int defaultParam)
12831283
{
12841284
}
1285+
1286+
void DLL_API FunctionWithPointerToEnumAsDefaultParameter(Enum* defaultParam1, int* defaultParam2)
1287+
{
1288+
}
1289+
1290+
DLL_API struct Bar DefaultBar;
1291+
1292+
DLL_API struct Bar* FunctionWithNonPrimitiveAsDefaultParameter(struct Bar& defaultParam)
1293+
{
1294+
return defaultParam.returnPointerToValueType();
1295+
}

tests/dotnet/Common/Common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,3 +1575,9 @@ const int ConstFlag2 = 2;
15751575
const int ConstFlag3 = 4;
15761576

15771577
void DLL_API FunctionWithConstFlagsAsDefaultParameter(int defaultParam = ConstFlag1 | ConstFlag2 | ConstFlag3);
1578+
1579+
void DLL_API FunctionWithPointerToEnumAsDefaultParameter(Enum* defaultParam1 = NULL, int* defaultParam2 = NULL);
1580+
1581+
extern DLL_API struct Bar DefaultBar;
1582+
1583+
DLL_API struct Bar* FunctionWithNonPrimitiveAsDefaultParameter(struct Bar& defaultParam = DefaultBar);

0 commit comments

Comments
 (0)