Browse Source

Reverted the representation of Booleans as managed Booleans except in internal structs.

Managed booleans are more CPU-efficient than bytes, and some problems with code generation are fixed.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/575/head
Dimitar Dobrev 10 years ago
parent
commit
54e8a16fd1
  1. 24
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 14
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 72
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  4. 4
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  5. 2
      tests/CSharp/CSharp.cs

24
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -12,7 +12,9 @@ namespace CppSharp.Generators.CSharp @@ -12,7 +12,9 @@ namespace CppSharp.Generators.CSharp
public enum CSharpMarshalKind
{
Unknown,
NativeField
NativeField,
GenericDelegate,
DefaultExpression
}
public class CSharpMarshalContext : MarshalContext
@ -212,9 +214,13 @@ namespace CppSharp.Generators.CSharp @@ -212,9 +214,13 @@ namespace CppSharp.Generators.CSharp
case PrimitiveType.Char16:
return false;
case PrimitiveType.Bool:
// returned structs must be blittable and bool isn't
Context.Return.Write("{0} != 0", Context.ReturnVarName);
return true;
if (Context.Kind == CSharpMarshalKind.NativeField)
{
// returned structs must be blittable and bool isn't
Context.Return.Write("{0} != 0", Context.ReturnVarName);
return true;
}
goto default;
default:
Context.Return.Write(Context.ReturnVarName);
return true;
@ -579,9 +585,13 @@ namespace CppSharp.Generators.CSharp @@ -579,9 +585,13 @@ namespace CppSharp.Generators.CSharp
case PrimitiveType.Char16:
return false;
case PrimitiveType.Bool:
// returned structs must be blittable and bool isn't
Context.Return.Write("(byte) ({0} ? 1 : 0)", Context.Parameter.Name);
return true;
if (Context.Kind == CSharpMarshalKind.NativeField)
{
// returned structs must be blittable and bool isn't
Context.Return.Write("(byte) ({0} ? 1 : 0)", Context.Parameter.Name);
return true;
}
goto default;
default:
Context.Return.Write(Context.Parameter.Name);
return true;

14
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -741,7 +741,9 @@ namespace CppSharp.Generators.CSharp @@ -741,7 +741,9 @@ namespace CppSharp.Generators.CSharp
WriteLine("[FieldOffset({0})]", field.OffsetInBytes);
TypePrinter.PushMarshalKind(CSharpMarshalKind.NativeField);
var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter);
TypePrinter.PopMarshalKind();
var typeName = safeIdentifier;
if (!string.IsNullOrWhiteSpace(fieldTypePrinted.NameSuffix))
@ -888,6 +890,7 @@ namespace CppSharp.Generators.CSharp @@ -888,6 +890,7 @@ namespace CppSharp.Generators.CSharp
NewLine();
WriteStartBraceIndent();
ctx.Kind = CSharpMarshalKind.NativeField;
var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
var arrayType = field.Type as ArrayType;
@ -2516,13 +2519,6 @@ namespace CppSharp.Generators.CSharp @@ -2516,13 +2519,6 @@ namespace CppSharp.Generators.CSharp
&& !string.IsNullOrWhiteSpace(param.Context.ArgumentPrefix))
name.Append(param.Context.ArgumentPrefix);
// returned structs must be blittable and bool isn't
if ((param.Param.Type.GetFinalPointee() ?? param.Param.Type).IsPrimitiveType(PrimitiveType.Bool))
{
var typePrinter = new CSharpTypePrinter(Driver);
typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
name.AppendFormat("({0}) ", param.Param.Type.Visit(typePrinter));
}
name.Append(param.Name);
names.Add(name.ToString());
}
@ -2702,9 +2698,7 @@ namespace CppSharp.Generators.CSharp @@ -2702,9 +2698,7 @@ namespace CppSharp.Generators.CSharp
PrimitiveType primitive;
// Do not delete instance in MS ABI.
var name = param.Kind == ParameterKind.ImplicitDestructorParameter ? "0" : param.Name;
// returned structs must be blittable and bool and char aren't
if (param.Type.IsPrimitiveType(out primitive) &&
primitive != PrimitiveType.Char && primitive != PrimitiveType.Bool)
if (param.Type.IsPrimitiveType(out primitive) && primitive != PrimitiveType.Char)
{
return new ParamMarshal { Name = name, Param = param };
}

72
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -11,27 +11,14 @@ namespace CppSharp.Generators.CSharp @@ -11,27 +11,14 @@ namespace CppSharp.Generators.CSharp
public enum CSharpTypePrinterContextKind
{
Native,
Managed,
ManagedPointer,
GenericDelegate,
DefaultExpression
Managed
}
public class CSharpTypePrinterContext : TypePrinterContext
{
public CSharpTypePrinterContextKind CSharpKind;
public CSharpMarshalKind MarshalKind;
public QualifiedType FullType;
public CSharpTypePrinterContext()
{
}
public CSharpTypePrinterContext(TypePrinterContextKind kind,
CSharpTypePrinterContextKind csharpKind) : base(kind)
{
CSharpKind = csharpKind;
}
}
public class CSharpTypePrinterResult
@ -42,7 +29,7 @@ namespace CppSharp.Generators.CSharp @@ -42,7 +29,7 @@ namespace CppSharp.Generators.CSharp
public static implicit operator CSharpTypePrinterResult(string type)
{
return new CSharpTypePrinterResult() {Type = type};
return new CSharpTypePrinterResult {Type = type};
}
public override string ToString()
@ -57,12 +44,18 @@ namespace CppSharp.Generators.CSharp @@ -57,12 +44,18 @@ namespace CppSharp.Generators.CSharp
private readonly Driver driver;
private readonly Stack<CSharpTypePrinterContextKind> contexts;
private readonly Stack<CSharpMarshalKind> marshalKinds;
public CSharpTypePrinterContextKind ContextKind
{
get { return contexts.Peek(); }
}
public CSharpMarshalKind MarshalKind
{
get { return marshalKinds.Peek(); }
}
public CSharpTypePrinterContext Context;
public CSharpTypePrinter(Driver driver)
@ -70,7 +63,9 @@ namespace CppSharp.Generators.CSharp @@ -70,7 +63,9 @@ namespace CppSharp.Generators.CSharp
this.driver = driver;
contexts = new Stack<CSharpTypePrinterContextKind>();
marshalKinds = new Stack<CSharpMarshalKind>();
PushContext(CSharpTypePrinterContextKind.Managed);
PushMarshalKind(CSharpMarshalKind.Unknown);
Context = new CSharpTypePrinterContext();
}
@ -85,16 +80,27 @@ namespace CppSharp.Generators.CSharp @@ -85,16 +80,27 @@ namespace CppSharp.Generators.CSharp
return contexts.Pop();
}
public void PushMarshalKind(CSharpMarshalKind marshalKind)
{
marshalKinds.Push(marshalKind);
}
public CSharpMarshalKind PopMarshalKind()
{
return marshalKinds.Pop();
}
public CSharpTypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals)
{
if (tag.Declaration == null)
return string.Empty;
TypeMap typeMap;
if (this.driver.TypeDatabase.FindTypeMap(tag.Declaration, out typeMap))
if (driver.TypeDatabase.FindTypeMap(tag.Declaration, out typeMap))
{
typeMap.Type = tag;
Context.CSharpKind = ContextKind;
Context.MarshalKind = MarshalKind;
Context.Type = tag;
string type = typeMap.CSharpSignature(Context);
@ -160,12 +166,12 @@ namespace CppSharp.Generators.CSharp @@ -160,12 +166,12 @@ namespace CppSharp.Generators.CSharp
var returnType = function.ReturnType;
var args = string.Empty;
PushContext(CSharpTypePrinterContextKind.GenericDelegate);
PushMarshalKind(CSharpMarshalKind.GenericDelegate);
if (arguments.Count > 0)
args = VisitParameters(function.Parameters, hasNames: false).Type;
PopContext();
PopMarshalKind();
if (ContextKind != CSharpTypePrinterContextKind.Managed)
return "global::System.IntPtr";
@ -180,11 +186,11 @@ namespace CppSharp.Generators.CSharp @@ -180,11 +186,11 @@ namespace CppSharp.Generators.CSharp
if (!string.IsNullOrEmpty(args))
args = string.Format(", {0}", args);
PushContext(CSharpTypePrinterContextKind.GenericDelegate);
PushMarshalKind(CSharpMarshalKind.GenericDelegate);
var returnTypePrinterResult = returnType.Visit(this);
PopContext();
PopMarshalKind();
return string.Format("Func<{0}{1}>", returnTypePrinterResult, args);
}
@ -215,7 +221,7 @@ namespace CppSharp.Generators.CSharp @@ -215,7 +221,7 @@ namespace CppSharp.Generators.CSharp
return IsConstCharString(qualType.Type);
}
bool AllowStrings = true;
private bool allowStrings = true;
public CSharpTypePrinterResult VisitPointerType(PointerType pointer,
TypeQualifiers quals)
@ -230,7 +236,7 @@ namespace CppSharp.Generators.CSharp @@ -230,7 +236,7 @@ namespace CppSharp.Generators.CSharp
var isManagedContext = ContextKind == CSharpTypePrinterContextKind.Managed;
if (AllowStrings && IsConstCharString(pointer))
if (allowStrings && IsConstCharString(pointer))
return isManagedContext ? "string" : "global::System.IntPtr";
var desugared = pointee.Desugar();
@ -251,15 +257,15 @@ namespace CppSharp.Generators.CSharp @@ -251,15 +257,15 @@ namespace CppSharp.Generators.CSharp
if (isManagedContext && isRefParam)
return pointee.Visit(this, quals);
if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate ||
if (MarshalKind == CSharpMarshalKind.GenericDelegate ||
pointee.IsPrimitiveType(PrimitiveType.Void))
return "global::System.IntPtr";
// Do not allow strings inside primitive arrays case, else we'll get invalid types
// like string* for const char **.
AllowStrings = isRefParam;
allowStrings = isRefParam;
var result = pointee.Visit(this, quals);
AllowStrings = true;
allowStrings = true;
return !isRefParam && result.Type == "global::System.IntPtr" ? "void**" : result + "*";
}
@ -297,9 +303,6 @@ namespace CppSharp.Generators.CSharp @@ -297,9 +303,6 @@ namespace CppSharp.Generators.CSharp
// TODO: Non-function member pointer types are tricky to support.
// Re-visit this.
return "global::System.IntPtr";
throw new InvalidOperationException(
"A function pointer not pointing to a function type.");
}
public CSharpTypePrinterResult VisitBuiltinType(BuiltinType builtin,
@ -314,10 +317,11 @@ namespace CppSharp.Generators.CSharp @@ -314,10 +317,11 @@ namespace CppSharp.Generators.CSharp
var decl = typedef.Declaration;
TypeMap typeMap;
if (this.driver.TypeDatabase.FindTypeMap(decl, out typeMap))
if (driver.TypeDatabase.FindTypeMap(decl, out typeMap))
{
typeMap.Type = typedef;
Context.CSharpKind = ContextKind;
Context.MarshalKind = MarshalKind;
Context.Type = typedef;
string type = typeMap.CSharpSignature(Context);
@ -360,7 +364,7 @@ namespace CppSharp.Generators.CSharp @@ -360,7 +364,7 @@ namespace CppSharp.Generators.CSharp
{
var decl = template.Template.TemplatedDecl;
TypeMap typeMap = null;
TypeMap typeMap;
if (!driver.TypeDatabase.FindTypeMap(template, out typeMap))
return GetNestedQualifiedName(decl) +
(ContextKind == CSharpTypePrinterContextKind.Native
@ -370,6 +374,7 @@ namespace CppSharp.Generators.CSharp @@ -370,6 +374,7 @@ namespace CppSharp.Generators.CSharp
typeMap.Type = template;
Context.Type = template;
Context.CSharpKind = ContextKind;
Context.MarshalKind = MarshalKind;
var type = GetCSharpSignature(typeMap);
if (!string.IsNullOrEmpty(type))
@ -389,6 +394,7 @@ namespace CppSharp.Generators.CSharp @@ -389,6 +394,7 @@ namespace CppSharp.Generators.CSharp
private string GetCSharpSignature(TypeMap typeMap)
{
Context.CSharpKind = ContextKind;
Context.MarshalKind = MarshalKind;
return typeMap.CSharpSignature(Context);
}
@ -493,7 +499,7 @@ namespace CppSharp.Generators.CSharp @@ -493,7 +499,7 @@ namespace CppSharp.Generators.CSharp
{
case PrimitiveType.Bool:
// returned structs must be blittable and bool isn't
return ContextKind == CSharpTypePrinterContextKind.Native ?
return MarshalKind == CSharpMarshalKind.NativeField ?
"byte" : "bool";
case PrimitiveType.Void: return "void";
case PrimitiveType.Char16:
@ -513,7 +519,7 @@ namespace CppSharp.Generators.CSharp @@ -513,7 +519,7 @@ namespace CppSharp.Generators.CSharp
case PrimitiveType.ULong:
case PrimitiveType.LongLong:
case PrimitiveType.ULongLong:
return GetIntString(primitive, this.driver.TargetInfo);
return GetIntString(primitive, driver.TargetInfo);
case PrimitiveType.Float: return "float";
case PrimitiveType.Double: return "double";
case PrimitiveType.IntPtr: return "global::System.IntPtr";

4
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -117,7 +117,7 @@ namespace CppSharp.Passes @@ -117,7 +117,7 @@ namespace CppSharp.Passes
TypeMap typeMap;
var typePrinter = new CSharpTypePrinter(Driver);
typePrinter.PushContext(CSharpTypePrinterContextKind.DefaultExpression);
typePrinter.PushMarshalKind(CSharpMarshalKind.DefaultExpression);
var typePrinterResult = type.Visit(typePrinter).Type;
if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
{
@ -259,7 +259,7 @@ namespace CppSharp.Passes @@ -259,7 +259,7 @@ namespace CppSharp.Passes
{
var typeInSignature = typeMap.CSharpSignatureType(new CSharpTypePrinterContext
{
CSharpKind = CSharpTypePrinterContextKind.DefaultExpression,
MarshalKind = CSharpMarshalKind.DefaultExpression,
Type = desugared
}).SkipPointerRefs().Desugar();
Enumeration @enum;

2
tests/CSharp/CSharp.cs

@ -62,7 +62,7 @@ namespace CppSharp.Tests @@ -62,7 +62,7 @@ namespace CppSharp.Tests
return Type.IsAddress() ? "QList.Internal*" : "QList.Internal";
return string.Format("System.Collections.Generic.{0}<{1}>",
ctx.CSharpKind == CSharpTypePrinterContextKind.DefaultExpression ? "List" : "IList",
ctx.MarshalKind == CSharpMarshalKind.DefaultExpression ? "List" : "IList",
ctx.GetTemplateParameterList());
}

Loading…
Cancel
Save