Skip to content

Commit a65f919

Browse files
committed
Handled int and long in maps to help resolve ambiguity.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent efa11ab commit a65f919

File tree

10 files changed

+164
-66
lines changed

10 files changed

+164
-66
lines changed

src/Generator/Driver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.CodeDom.Compiler;
33
using System.Collections.Generic;
4-
using System.Globalization;
54
using System.IO;
65
using System.Linq;
76
using System.Text;
@@ -73,7 +72,7 @@ public void Setup()
7372
}
7473

7574
public void SetupTypeMaps() =>
76-
Context.TypeMaps = new TypeMapDatabase(Context.ASTContext, Options);
75+
Context.TypeMaps = new TypeMapDatabase(Context);
7776

7877
void OnSourceFileParsed(IEnumerable<string> files, ParserResult result)
7978
{

src/Generator/Generators/CSharp/CSharpTypePrinter.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,23 @@ public override TypePrinterResult VisitArrayType(ArrayType array,
133133
return $"{arrayType.Visit(this)}{arraySuffix}";
134134
}
135135

136+
public override TypePrinterResult VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
137+
{
138+
TypeMap typeMap;
139+
if (TypeMapDatabase.FindTypeMap(builtin, out typeMap))
140+
{
141+
var typePrinterContext = new TypePrinterContext()
142+
{
143+
Kind = Kind,
144+
MarshalKind = MarshalKind,
145+
Type = builtin,
146+
Parameter = Parameter
147+
};
148+
return typeMap.CSharpSignatureType(typePrinterContext).Visit(this);
149+
}
150+
return base.VisitBuiltinType(builtin, quals);
151+
}
152+
136153
public override TypePrinterResult VisitFunctionType(FunctionType function,
137154
TypeQualifiers quals)
138155
{
@@ -776,6 +793,40 @@ public TypePrinterResult PrintNative(QualifiedType type)
776793
return typePrinterResult;
777794
}
778795

796+
public static Type GetSignedType(uint width)
797+
{
798+
switch (width)
799+
{
800+
case 8:
801+
return new CILType(typeof(sbyte));
802+
case 16:
803+
return new CILType(typeof(short));
804+
case 32:
805+
return new CILType(typeof(int));
806+
case 64:
807+
return new CILType(typeof(long));
808+
default:
809+
throw new System.NotSupportedException();
810+
}
811+
}
812+
813+
public static Type GetUnsignedType(uint width)
814+
{
815+
switch (width)
816+
{
817+
case 8:
818+
return new CILType(typeof(byte));
819+
case 16:
820+
return new CILType(typeof(ushort));
821+
case 32:
822+
return new CILType(typeof(uint));
823+
case 64:
824+
return new CILType(typeof(ulong));
825+
default:
826+
throw new System.NotSupportedException();
827+
}
828+
}
829+
779830
private static bool IsValid(TemplateArgument a)
780831
{
781832
if (a.Type.Type == null)

src/Generator/Passes/CheckOperatorsOverloads.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ static CXXOperatorKind CheckMissingOperatorOverloadPair(Class @class, out int in
185185
return CXXOperatorKind.None;
186186
}
187187

188-
static bool IsValidOperatorOverload(Method @operator)
188+
private bool IsValidOperatorOverload(Method @operator)
189189
{
190190
// These follow the order described in MSDN (Overloadable Operators).
191191

@@ -235,9 +235,31 @@ static bool IsValidOperatorOverload(Method @operator)
235235
// Bitwise shift operators can only be overloaded if the second parameter is int
236236
case CXXOperatorKind.LessLess:
237237
case CXXOperatorKind.GreaterGreater:
238-
PrimitiveType primitiveType;
239-
return @operator.Parameters.Last().Type.IsPrimitiveType(out primitiveType) &&
240-
primitiveType == PrimitiveType.Int;
238+
{
239+
Parameter parameter = @operator.Parameters.Last();
240+
Type type = parameter.Type.Desugar();
241+
switch (Options.GeneratorKind)
242+
{
243+
case GeneratorKind.CLI:
244+
return type.IsPrimitiveType(PrimitiveType.Int);
245+
case GeneratorKind.CSharp:
246+
Types.TypeMap typeMap;
247+
if (Context.TypeMaps.FindTypeMap(type, out typeMap))
248+
{
249+
var mappedTo = typeMap.CSharpSignatureType(
250+
new TypePrinterContext
251+
{
252+
Parameter = parameter,
253+
Type = type
254+
});
255+
var cilType = mappedTo as CILType;
256+
if (cilType?.Type == typeof(int))
257+
return true;
258+
}
259+
break;
260+
}
261+
return false;
262+
}
241263

242264
// No parameters means the dereference operator - cannot be overloaded
243265
case CXXOperatorKind.Star:

src/Generator/Types/Std/Stdlib.cs

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,46 @@ public class VaList : TypeMap
1616
public override bool IsIgnored => true;
1717
}
1818

19+
[TypeMap("int", GeneratorKind = GeneratorKind.CSharp)]
20+
public class Int : TypeMap
21+
{
22+
public override Type CSharpSignatureType(TypePrinterContext ctx) =>
23+
CSharpTypePrinter.GetSignedType(Context.TargetInfo.IntWidth);
24+
}
25+
26+
[TypeMap("unsigned int", GeneratorKind = GeneratorKind.CSharp)]
27+
public class UnsignedInt : TypeMap
28+
{
29+
public override Type CSharpSignatureType(TypePrinterContext ctx) =>
30+
CSharpTypePrinter.GetUnsignedType(Context.TargetInfo.IntWidth);
31+
}
32+
33+
[TypeMap("long", GeneratorKind = GeneratorKind.CSharp)]
34+
public class Long : TypeMap
35+
{
36+
public override Type CSharpSignatureType(TypePrinterContext ctx) =>
37+
CSharpTypePrinter.GetSignedType(Context.TargetInfo.LongWidth);
38+
}
39+
40+
[TypeMap("unsigned long", GeneratorKind = GeneratorKind.CSharp)]
41+
public class UnsignedLong : TypeMap
42+
{
43+
public override Type CSharpSignatureType(TypePrinterContext ctx) =>
44+
CSharpTypePrinter.GetUnsignedType(Context.TargetInfo.LongWidth);
45+
}
46+
1947
[TypeMap("char", GeneratorKind = GeneratorKind.CSharp)]
2048
public class Char : TypeMap
2149
{
2250
public override Type CSharpSignatureType(TypePrinterContext ctx)
2351
{
2452
return new CILType(ctx.Kind == TypePrinterContextKind.Native ||
25-
!Options.MarshalCharAsManagedChar ? typeof(sbyte) : typeof(char));
53+
!Context.Options.MarshalCharAsManagedChar ? typeof(sbyte) : typeof(char));
2654
}
2755

2856
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
2957
{
30-
if (Options.MarshalCharAsManagedChar)
58+
if (Context.Options.MarshalCharAsManagedChar)
3159
ctx.Return.Write("global::System.Convert.ToSByte({0})",
3260
ctx.Parameter.Name);
3361
else
@@ -36,7 +64,7 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
3664

3765
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
3866
{
39-
if (Options.MarshalCharAsManagedChar)
67+
if (Context.Options.MarshalCharAsManagedChar)
4068
ctx.Return.Write("global::System.Convert.ToChar({0})",
4169
ctx.ReturnVarName);
4270
else
@@ -51,16 +79,6 @@ public override Type CSharpSignatureType(TypePrinterContext ctx)
5179
{
5280
return new CILType(typeof(char));
5381
}
54-
55-
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
56-
{
57-
ctx.Return.Write(ctx.Parameter.Name);
58-
}
59-
60-
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
61-
{
62-
ctx.Return.Write(ctx.ReturnVarName);
63-
}
6482
}
6583

6684
[TypeMap("wchar_t", GeneratorKind = GeneratorKind.CSharp)]
@@ -70,16 +88,6 @@ public override Type CSharpSignatureType(TypePrinterContext ctx)
7088
{
7189
return new CILType(typeof(char));
7290
}
73-
74-
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
75-
{
76-
ctx.Return.Write(ctx.Parameter.Name);
77-
}
78-
79-
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
80-
{
81-
ctx.Return.Write(ctx.ReturnVarName);
82-
}
8391
}
8492

8593
[TypeMap("const char*", GeneratorKind = GeneratorKind.CSharp)]
@@ -92,13 +100,13 @@ public override Type CSharpSignatureType(TypePrinterContext ctx)
92100

93101
if (ctx.Parameter == null || ctx.Parameter.Name == Helpers.ReturnIdentifier)
94102
return new CustomType(CSharpTypePrinter.IntPtrType);
95-
if (Options.Encoding == Encoding.ASCII)
103+
if (Context.Options.Encoding == Encoding.ASCII)
96104
return new CustomType("[MarshalAs(UnmanagedType.LPStr)] string");
97-
if (Options.Encoding == Encoding.Unicode ||
98-
Options.Encoding == Encoding.BigEndianUnicode)
105+
if (Context.Options.Encoding == Encoding.Unicode ||
106+
Context.Options.Encoding == Encoding.BigEndianUnicode)
99107
return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string");
100108
throw new System.NotSupportedException(
101-
$"{Options.Encoding.EncodingName} is not supported yet.");
109+
$"{Context.Options.Encoding.EncodingName} is not supported yet.");
102110
}
103111

104112
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
@@ -111,19 +119,19 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
111119
ctx.Return.Write(ctx.Parameter.Name);
112120
return;
113121
}
114-
if (Equals(Options.Encoding, Encoding.ASCII))
122+
if (Equals(Context.Options.Encoding, Encoding.ASCII))
115123
{
116124
ctx.Return.Write($"Marshal.StringToHGlobalAnsi({ctx.Parameter.Name})");
117125
return;
118126
}
119-
if (Equals(Options.Encoding, Encoding.Unicode) ||
120-
Equals(Options.Encoding, Encoding.BigEndianUnicode))
127+
if (Equals(Context.Options.Encoding, Encoding.Unicode) ||
128+
Equals(Context.Options.Encoding, Encoding.BigEndianUnicode))
121129
{
122130
ctx.Return.Write($"Marshal.StringToHGlobalUni({ctx.Parameter.Name})");
123131
return;
124132
}
125133
throw new System.NotSupportedException(
126-
$"{Options.Encoding.EncodingName} is not supported yet.");
134+
$"{Context.Options.Encoding.EncodingName} is not supported yet.");
127135
}
128136

129137
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
@@ -144,7 +152,7 @@ public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
144152
var encoding = isChar ? Encoding.ASCII : Encoding.Unicode;
145153

146154
if (Equals(encoding, Encoding.ASCII))
147-
encoding = Options.Encoding;
155+
encoding = Context.Options.Encoding;
148156

149157
if (Equals(encoding, Encoding.ASCII))
150158
{
@@ -579,15 +587,5 @@ public override Type CSharpSignatureType(TypePrinterContext ctx)
579587
{
580588
return new CILType(typeof(System.IntPtr));
581589
}
582-
583-
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
584-
{
585-
ctx.Return.Write(ctx.Parameter.Name);
586-
}
587-
588-
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
589-
{
590-
ctx.Return.Write(ctx.ReturnVarName);
591-
}
592590
}
593591
}

src/Generator/Types/TypeMap.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public TypeMapAttribute(string type, GeneratorKind generatorKind)
3535
public class TypeMap
3636
{
3737
public Type Type { get; set; }
38-
public ASTContext ASTContext { get; set; }
39-
public DriverOptions Options { get; set; }
38+
public BindingContext Context { get; set; }
4039
public ITypeMapDatabase TypeMapDatabase { get; set; }
4140

4241
public bool IsEnabled { get; set; } = true;
@@ -59,12 +58,12 @@ public virtual Type CSharpSignatureType(TypePrinterContext ctx)
5958

6059
public virtual void CSharpMarshalToNative(CSharpMarshalContext ctx)
6160
{
62-
throw new NotImplementedException();
61+
ctx.Return.Write(ctx.Parameter.Name);
6362
}
6463

6564
public virtual void CSharpMarshalToManaged(CSharpMarshalContext ctx)
6665
{
67-
throw new NotImplementedException();
66+
ctx.Return.Write(ctx.ReturnVarName);
6867
}
6968

7069
/// <summary>
@@ -91,12 +90,12 @@ public virtual void CLITypeReference(CLITypeReferenceCollector collector, ASTRec
9190

9291
public virtual void CLIMarshalToNative(MarshalContext ctx)
9392
{
94-
throw new NotImplementedException();
93+
ctx.Return.Write(ctx.Parameter.Name);
9594
}
9695

9796
public virtual void CLIMarshalToManaged(MarshalContext ctx)
9897
{
99-
throw new NotImplementedException();
98+
ctx.Return.Write(ctx.ReturnVarName);
10099
}
101100

102101
#endregion

0 commit comments

Comments
 (0)