Skip to content

Commit 43bb2ee

Browse files
committed
Added a type map for char.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent c75d665 commit 43bb2ee

File tree

9 files changed

+88
-54
lines changed

9 files changed

+88
-54
lines changed

src/AST/CppTypePrinter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private static string ConvertModifierToString(PointerType.TypeModifier modifier)
6565
{
6666
switch (modifier)
6767
{
68-
case PointerType.TypeModifier.Value: return string.Empty;
68+
case PointerType.TypeModifier.Value: return "[]";
6969
case PointerType.TypeModifier.Pointer: return "*";
7070
case PointerType.TypeModifier.LVReference: return "&";
7171
case PointerType.TypeModifier.RVReference: return "&&";

src/Generator/Driver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void Setup()
7373
}
7474

7575
public void SetupTypeMaps() =>
76-
Context.TypeMaps = new TypeMapDatabase(Context.ASTContext, Options.GeneratorKind);
76+
Context.TypeMaps = new TypeMapDatabase(Context.ASTContext, Options);
7777

7878
void OnSourceFileParsed(IEnumerable<string> files, ParserResult result)
7979
{

src/Generator/Generators/CLI/CLIMarshal.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Text;
44
using CppSharp.AST;
55
using CppSharp.AST.Extensions;
6-
using CppSharp.Generators.CSharp;
76
using CppSharp.Types;
87
using Delegate = CppSharp.AST.Delegate;
98
using Type = CppSharp.AST.Type;
@@ -22,7 +21,6 @@ public override bool VisitType(Type type, TypeQualifiers quals)
2221
TypeMap typeMap;
2322
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) && typeMap.DoesMarshalling)
2423
{
25-
typeMap.Type = type;
2624
typeMap.CLIMarshalToManaged(Context);
2725
return false;
2826
}
@@ -430,7 +428,6 @@ public override bool VisitType(Type type, TypeQualifiers quals)
430428
TypeMap typeMap;
431429
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) && typeMap.DoesMarshalling)
432430
{
433-
typeMap.Type = type;
434431
typeMap.CLIMarshalToNative(Context);
435432
return false;
436433
}

src/Generator/Generators/CLI/CLITypePrinter.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public override TypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals
2525
TypeMap typeMap = null;
2626
if (TypeMapDatabase.FindTypeMap(tag, out typeMap))
2727
{
28-
typeMap.Type = tag;
2928
var typePrinterContext = new TypePrinterContext { Type = tag };
3029
return typeMap.CLISignatureType(typePrinterContext).ToString();
3130
}
@@ -225,7 +224,6 @@ public override TypePrinterResult VisitTemplateSpecializationType(
225224
TypeMap typeMap = null;
226225
if (TypeMapDatabase.FindTypeMap(template, out typeMap) && !typeMap.IsIgnored)
227226
{
228-
typeMap.Type = template;
229227
var typePrinterContext = new TypePrinterContext { Type = template };
230228
return typeMap.CLISignatureType(typePrinterContext).ToString();
231229
}

src/Generator/Generators/CSharp/CSharpMarshal.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public override bool VisitType(Type type, TypeQualifiers quals)
5353
TypeMap typeMap;
5454
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) && typeMap.DoesMarshalling)
5555
{
56-
typeMap.Type = type;
5756
typeMap.CSharpMarshalToManaged(Context);
5857
return false;
5958
}
@@ -237,15 +236,6 @@ public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers
237236
{
238237
case PrimitiveType.Void:
239238
return true;
240-
case PrimitiveType.Char:
241-
// returned structs must be blittable and char isn't
242-
if (Context.Context.Options.MarshalCharAsManagedChar)
243-
{
244-
Context.Return.Write("global::System.Convert.ToChar({0})",
245-
Context.ReturnVarName);
246-
return true;
247-
}
248-
goto default;
249239
case PrimitiveType.Bool:
250240
if (Context.MarshalKind == MarshalKind.NativeField)
251241
{
@@ -469,7 +459,6 @@ public override bool VisitType(Type type, TypeQualifiers quals)
469459
TypeMap typeMap;
470460
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) && typeMap.DoesMarshalling)
471461
{
472-
typeMap.Type = type;
473462
typeMap.CSharpMarshalToNative(Context);
474463
return false;
475464
}
@@ -727,15 +716,6 @@ public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers
727716
{
728717
case PrimitiveType.Void:
729718
return true;
730-
case PrimitiveType.Char:
731-
// returned structs must be blittable and char isn't
732-
if (Context.Context.Options.MarshalCharAsManagedChar)
733-
{
734-
Context.Return.Write("global::System.Convert.ToSByte({0})",
735-
Context.Parameter.Name);
736-
return true;
737-
}
738-
goto default;
739719
case PrimitiveType.Bool:
740720
if (Context.MarshalKind == MarshalKind.NativeField)
741721
{

src/Generator/Passes/CheckDuplicatedNamesPass.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,8 @@ public bool Equals(Parameter x, Parameter y)
106106
// TODO: some target languages might make a difference between values and pointers
107107
Type leftPointee = left.GetPointee();
108108
Type rightPointee = right.GetPointee();
109-
if ((leftPointee != null && leftPointee.Desugar(false).Equals(right)) ||
110-
(rightPointee != null && rightPointee.Desugar(false).Equals(left)))
111-
return true;
112-
113-
return TypePrinter != null &&
114-
left.IsPrimitiveType() && right.IsPrimitiveType() &&
115-
left.Visit(TypePrinter).Type == right.Visit(TypePrinter).Type;
109+
return (leftPointee != null && leftPointee.Desugar(false).Equals(right)) ||
110+
(rightPointee != null && rightPointee.Desugar(false).Equals(left));
116111
}
117112

118113
public int GetHashCode(Parameter obj)

src/Generator/Types/Std/Stdlib.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,72 @@ public class VaList : TypeMap
1515
public override bool IsIgnored => true;
1616
}
1717

18+
[TypeMap("char", GeneratorKind = GeneratorKind.CSharp)]
19+
public class Char : TypeMap
20+
{
21+
public override Type CSharpSignatureType(TypePrinterContext ctx)
22+
{
23+
return new CILType(ctx.Kind == TypePrinterContextKind.Native ||
24+
!Options.MarshalCharAsManagedChar ? typeof(sbyte) : typeof(char));
25+
}
26+
27+
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
28+
{
29+
if (Options.MarshalCharAsManagedChar)
30+
ctx.Return.Write("global::System.Convert.ToSByte({0})",
31+
ctx.Parameter.Name);
32+
else
33+
ctx.Return.Write(ctx.Parameter.Name);
34+
}
35+
36+
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
37+
{
38+
if (Options.MarshalCharAsManagedChar)
39+
ctx.Return.Write("global::System.Convert.ToChar({0})",
40+
ctx.ReturnVarName);
41+
else
42+
ctx.Return.Write(ctx.ReturnVarName);
43+
}
44+
}
45+
46+
[TypeMap("char16_t", GeneratorKind = GeneratorKind.CSharp)]
47+
public class Char16T : TypeMap
48+
{
49+
public override Type CSharpSignatureType(TypePrinterContext ctx)
50+
{
51+
return new CILType(typeof(char));
52+
}
53+
54+
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
55+
{
56+
ctx.Return.Write(ctx.Parameter.Name);
57+
}
58+
59+
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
60+
{
61+
ctx.Return.Write(ctx.ReturnVarName);
62+
}
63+
}
64+
65+
[TypeMap("wchar_t", GeneratorKind = GeneratorKind.CSharp)]
66+
public class WCharT : TypeMap
67+
{
68+
public override Type CSharpSignatureType(TypePrinterContext ctx)
69+
{
70+
return new CILType(typeof(char));
71+
}
72+
73+
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
74+
{
75+
ctx.Return.Write(ctx.Parameter.Name);
76+
}
77+
78+
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
79+
{
80+
ctx.Return.Write(ctx.ReturnVarName);
81+
}
82+
}
83+
1884
[TypeMap("basic_string<char, char_traits<char>, allocator<char>>")]
1985
public class String : TypeMap
2086
{

src/Generator/Types/TypeMap.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using CppSharp.AST;
4-
using CppSharp.AST.Extensions;
53
using CppSharp.Generators;
64
using CppSharp.Generators.AST;
75
using CppSharp.Generators.CLI;
@@ -14,7 +12,7 @@ namespace CppSharp.Types
1412
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
1513
public class TypeMapAttribute : Attribute
1614
{
17-
public string Type { get; private set; }
15+
public string Type { get; }
1816
public GeneratorKind GeneratorKind { get; set; }
1917

2018
public TypeMapAttribute(string type) : this(type, 0)
@@ -38,24 +36,19 @@ public class TypeMap
3836
{
3937
public Type Type { get; set; }
4038
public ASTContext ASTContext { get; set; }
39+
public DriverOptions Options { get; set; }
4140
public ITypeMapDatabase TypeMapDatabase { get; set; }
4241

4342
public bool IsEnabled { get; set; } = true;
4443

45-
public virtual bool IsIgnored
46-
{
47-
get { return false; }
48-
}
44+
public virtual bool IsIgnored => false;
4945

50-
public virtual bool IsValueType
51-
{
52-
get { return false; }
53-
}
46+
public virtual bool IsValueType => false;
5447

5548
/// <summary>
5649
/// Determines if the type map performs marshalling or only injects custom code.
5750
/// </summary>
58-
public virtual bool DoesMarshalling { get { return true; } }
51+
public virtual bool DoesMarshalling => true;
5952

6053
#region C# backend
6154

src/Generator/Types/TypeMapDatabase.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using CppSharp.AST;
44
using CppSharp.AST.Extensions;
5-
using CppSharp.Generators;
65
using Type = CppSharp.AST.Type;
76

87
namespace CppSharp.Types
@@ -11,15 +10,18 @@ public class TypeMapDatabase : ITypeMapDatabase
1110
{
1211
public IDictionary<string, TypeMap> TypeMaps { get; set; }
1312

14-
public TypeMapDatabase(ASTContext astContext, GeneratorKind generatorKind)
13+
public DriverOptions Options { get; }
14+
15+
public TypeMapDatabase(ASTContext astContext, DriverOptions options)
1516
{
1617
TypeMaps = new Dictionary<string, TypeMap>();
18+
this.Options = options;
1719
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
1820
{
1921
try
2022
{
2123
var types = assembly.FindDerivedTypes(typeof(TypeMap));
22-
SetupTypeMaps(types, generatorKind, astContext);
24+
SetupTypeMaps(types, astContext);
2325
}
2426
catch (System.Reflection.ReflectionTypeLoadException ex)
2527
{
@@ -29,18 +31,18 @@ public TypeMapDatabase(ASTContext astContext, GeneratorKind generatorKind)
2931
}
3032
}
3133

32-
private void SetupTypeMaps(IEnumerable<System.Type> types,
33-
GeneratorKind generatorKind, ASTContext astContext)
34+
private void SetupTypeMaps(IEnumerable<System.Type> types, ASTContext astContext)
3435
{
3536
foreach (var type in types)
3637
{
3738
var attrs = type.GetCustomAttributes(typeof(TypeMapAttribute), true);
3839
foreach (TypeMapAttribute attr in attrs)
3940
{
40-
if (attr.GeneratorKind == 0 || attr.GeneratorKind == generatorKind)
41+
if (attr.GeneratorKind == 0 || attr.GeneratorKind == Options.GeneratorKind)
4142
{
4243
var typeMap = (TypeMap) Activator.CreateInstance(type);
4344
typeMap.ASTContext = astContext;
45+
typeMap.Options = Options;
4446
typeMap.TypeMapDatabase = this;
4547
this.TypeMaps[attr.Type] = typeMap;
4648
}
@@ -108,10 +110,13 @@ public bool FindTypeMap(Type type, out TypeMap typeMap)
108110
return typeMap.IsEnabled;
109111
}
110112

113+
Type desugared = type.Desugar();
114+
bool printExtra = desugared.GetPointee() != null &&
115+
desugared.GetFinalPointee().Desugar().IsPrimitiveType();
111116
var typePrinter = new CppTypePrinter
112117
{
113-
PrintTypeQualifiers = false,
114-
PrintTypeModifiers = false,
118+
PrintTypeQualifiers = printExtra,
119+
PrintTypeModifiers = printExtra,
115120
PrintLogicalNames = true
116121
};
117122

0 commit comments

Comments
 (0)