Skip to content

Commit

Permalink
Fixed the generated C# for public fields with type a dependent pointer.
Browse files Browse the repository at this point in the history
Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information
ddobrev committed Dec 24, 2017
1 parent 4b31087 commit 6dec97f
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 21 deletions.
45 changes: 29 additions & 16 deletions src/Generator/Generators/CSharp/CSharpSources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,8 @@ private void GenerateFieldSetter(Field field, Class @class, QualifiedType fieldT
var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
ctx.Declaration = field;

var arrayType = field.Type.Desugar() as ArrayType;
Type type = field.Type.Desugar();
var arrayType = type as ArrayType;

if (arrayType != null && @class.IsValueType)
{
Expand All @@ -923,13 +924,20 @@ private void GenerateFieldSetter(Field field, Class @class, QualifiedType fieldT

if (marshal.Context.Return.StringBuilder.Length > 0)
{
WriteLine("{0} = {1}{2};", ctx.ReturnVarName,
field.Type.IsPointer() && field.Type.GetFinalPointee().IsPrimitiveType() &&
!CSharpTypePrinter.IsConstCharString(field.Type) ?
string.Format("({0}) ", CSharpTypePrinter.IntPtrType) :
string.Empty,
marshal.Context.Return);

Write($"{ctx.ReturnVarName} = ");
if (type.IsPointer())
{
Type pointee = type.GetFinalPointee();
if (pointee.IsPrimitiveType() &&
!CSharpTypePrinter.IsConstCharString(type))
{
Write($"({CSharpTypePrinter.IntPtrType}) ");
var templateSubstitution = pointee.Desugar(false) as TemplateParameterSubstitutionType;
if (templateSubstitution != null)
Write($"(object) ");
}
}
WriteLine($"{marshal.Context.Return};");
}

if ((arrayType != null && @class.IsValueType) || ctx.HasCodeBlock)
Expand Down Expand Up @@ -1191,21 +1199,26 @@ private void GenerateFieldGetter(Field field, Class @class, QualifiedType return
if (ctx.HasCodeBlock)
PushIndent();

Write("return ");

var @return = marshal.Context.Return.ToString();
if (field.Type.IsPointer())
{
var final = field.Type.GetFinalPointee().Desugar();
if (final.IsPrimitiveType() && !final.IsPrimitiveType(PrimitiveType.Void) &&
var final = field.Type.GetFinalPointee().Desugar(resolveTemplateSubstitution: false);
var templateSubstitution = final as TemplateParameterSubstitutionType;
if (templateSubstitution != null)
Write($"({templateSubstitution.ReplacedParameter.Parameter.Name}) (object) ");
if ((final.IsPrimitiveType() && !final.IsPrimitiveType(PrimitiveType.Void) &&
(!final.IsPrimitiveType(PrimitiveType.Char) &&
!final.IsPrimitiveType(PrimitiveType.WideChar) ||
(!Context.Options.MarshalCharAsManagedChar &&
!((PointerType) field.Type).QualifiedPointee.Qualifiers.IsConst)))
@return = string.Format("({0}*) {1}", field.Type.GetPointee().Desugar(), @return);
if (!((PointerType) field.Type).QualifiedPointee.Qualifiers.IsConst &&
final.IsPrimitiveType(PrimitiveType.WideChar))
@return = string.Format("({0}*) {1}", field.Type.GetPointee().Desugar(), @return);
!((PointerType) field.Type).QualifiedPointee.Qualifiers.IsConst)) &&
templateSubstitution == null) ||
(!((PointerType) field.Type).QualifiedPointee.Qualifiers.IsConst &&
final.IsPrimitiveType(PrimitiveType.WideChar)))
Write($"({field.Type.GetPointee().Desugar()}*) ");
}
WriteLine("return {0};", @return);
WriteLine($"{@return};");

if ((arrayType != null && @class.IsValueType) || ctx.HasCodeBlock)
WriteCloseBraceIndent();
Expand Down
4 changes: 2 additions & 2 deletions src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ public static void GenerateField(this CSharpSources gen, Class @class,
{
if (@class.IsDependent)
{
if (@class.Fields.Any(f => f.Type.Desugar() is TemplateParameterType))
if (@class.Fields.Any(f => f.Type.IsDependent))
{
foreach (var parameter in @class.TemplateParameters)
gen.WriteLine($"var __{parameter.Name} = typeof({parameter.Name});");

foreach (var specialization in @class.Specializations.Where(s => !s.Ignore))
foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
{
WriteTemplateSpecializationCheck(gen, @class, specialization);
gen.WriteStartBraceIndent();
Expand Down
3 changes: 2 additions & 1 deletion src/Generator/Passes/MultipleInheritancePass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ where property.IsDeclared
Namespace = @interface,
Name = "Dispose",
ReturnType = new QualifiedType(new BuiltinType(PrimitiveType.Void)),
SynthKind = FunctionSynthKind.InterfaceDispose
SynthKind = FunctionSynthKind.InterfaceDispose,
Mangled = string.Empty
};

@interface.Methods.Add(dispose);
Expand Down
8 changes: 8 additions & 0 deletions tests/CSharp/CSharp.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,14 @@ public void TestExtensionsOfSpecializationsAsSecondaryBases()
}
}

[Test]
public void TestFieldWithDependentPointerType()
{
using (var dependentPointerFields = new DependentPointerFields<float>())
{
}
}

[Test]
public void TestAbstractImplementatonsInPrimaryAndSecondaryBases()
{
Expand Down
18 changes: 16 additions & 2 deletions tests/CSharp/CSharpTemplates.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,22 @@ class DLL_API DerivedFromSpecializationOfUnsupportedTemplate : public DependentV
template <typename T>
class DLL_API DependentPointerFields
{
private:
public:
DependentPointerFields();
~DependentPointerFields();
T* field;
};

template <typename T>
DependentPointerFields<T>::DependentPointerFields()
{
}

template <typename T>
DependentPointerFields<T>::~DependentPointerFields()
{
}

template <typename K, typename V>
class TwoTemplateArgs
{
Expand Down Expand Up @@ -576,7 +588,8 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool>
TemplateWithIndexer<int> _10, TemplateWithIndexer<T1> _11,
TemplateWithIndexer<T2*> _12, TemplateWithIndexer<UsedInTemplatedIndexer> _13,
TemplateDerivedFromRegularDynamic<RegularDynamic> _14,
IndependentFields<OnlySpecialisedInTypeArg<double>> _15, std::string s);
IndependentFields<OnlySpecialisedInTypeArg<double>> _15,
DependentPointerFields<float> _16, std::string s);

void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii);

Expand All @@ -592,6 +605,7 @@ template class DLL_API IndependentFields<std::string>;
template class DLL_API Base<int>;
template class DLL_API DependentValueFields<int>;
template class DLL_API DependentValueFields<float>;
template class DLL_API DependentPointerFields<float>;
template class DLL_API VirtualTemplate<int>;
template class DLL_API VirtualTemplate<bool>;
template class DLL_API HasDefaultTemplateArgument<int, int>;
Expand Down

0 comments on commit 6dec97f

Please sign in to comment.