Permalink
Browse files

Extracted the native printing in C# to separate methods.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information...
ddobrev committed Aug 5, 2017
1 parent 5443445 commit 2af1af64046d6a16a8433c4be8fd9df7e8571857
@@ -609,11 +609,8 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
if (!marshalAsString &&
Context.Context.Options.MarshalCharAsManagedChar &&
primitive == PrimitiveType.Char)
{
typePrinter.PushContext(TypePrinterContextKind.Native);
Context.Return.Write(string.Format("({0}) ", pointer.Visit(typePrinter)));
typePrinter.PopContext();
}
Context.Return.Write($"({typePrinter.PrintNative(pointer)}) ");
if (marshalAsString && (Context.MarshalKind == MarshalKind.NativeField ||
Context.MarshalKind == MarshalKind.VTableReturnValue ||
Context.MarshalKind == MarshalKind.Variable))
@@ -784,9 +781,7 @@ private void MarshalRefClass(Class @class)
}
var realClass = @class.OriginalClass ?? @class;
typePrinter.PushContext(TypePrinterContextKind.Native);
var qualifiedIdentifier = realClass.Visit(typePrinter);
typePrinter.PopContext();
var qualifiedIdentifier = typePrinter.PrintNative(realClass);
Context.Return.Write(
"ReferenceEquals({0}, null) ? new {1}() : *({1}*) {2}",
param, qualifiedIdentifier, paramInstance);
@@ -847,15 +847,13 @@ private void GenerateFieldSetter(Field field, Class @class)
else
{
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
TypePrinter.PushContext(TypePrinterContextKind.Native);
var printed = TypePrinter.PrintNative(@class);
ctx.ReturnVarName = string.Format("{0}{1}{2}",
@class.IsValueType
? Helpers.InstanceField
: string.Format("(({0}*) {1})", @class.Visit(TypePrinter),
Helpers.InstanceIdentifier),
: $"(({printed}*) {Helpers.InstanceIdentifier})",
@class.IsValueType ? "." : "->",
SafeIdentifier(name));
TypePrinter.PopContext();
}
param.Visit(marshal);
@@ -889,15 +887,9 @@ private string HandleValueArray(ArrayType arrayType, Field field)
string type;
if (Context.Options.MarshalCharAsManagedChar && isChar)
{
var typePrinter = new CSharpTypePrinter(Context);
typePrinter.PushContext(TypePrinterContextKind.Native);
type = originalType.Visit(typePrinter).Type;
}
type = TypePrinter.PrintNative(originalType).Type;
else
{
type = originalType.ToString();
}
var name = ((Class) field.Namespace).Layout.Fields.First(
f => f.FieldPtr == field.OriginalPtr).Name;
@@ -1085,19 +1077,16 @@ private static Property GetActualProperty(Property property, Class c)
private void GenerateFieldGetter(Field field, Class @class)
{
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
TypePrinter.PushContext(TypePrinterContextKind.Native);
var ctx = new CSharpMarshalContext(Context)
{
ArgName = field.Name,
Declaration = field,
ReturnVarName = $@"{(@class.IsValueType ? Helpers.InstanceField :
$"(({@class.Visit(TypePrinter)}*) {Helpers.InstanceIdentifier})")}{
$"(({TypePrinter.PrintNative(@class)}*) {Helpers.InstanceIdentifier})")}{
(@class.IsValueType ? "." : "->")}{SafeIdentifier(name)}",
ReturnType = field.QualifiedType
};
ctx.PushMarshalKind(MarshalKind.NativeField);
TypePrinter.PopContext();
var arrayType = field.Type.Desugar() as ArrayType;
@@ -1442,7 +1431,6 @@ private void GenerateVTableClassSetup(Class @class, IList<VTableComponent> wrapp
private void SaveOriginalVTablePointers(Class @class)
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
if (Context.ParserOptions.IsMicrosoftAbi)
WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
string.Join(", ",
@@ -1452,7 +1440,6 @@ private void SaveOriginalVTablePointers(Class @class)
WriteLine(
$@"__OriginalVTables = new void*[] {{ *(void**) ({
Helpers.InstanceIdentifier} + {@class.Layout.VTablePointers[0].Offset}) }};");
TypePrinter.PopContext();
}
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries,
@@ -1630,10 +1617,9 @@ private void GenerateVTableManagedCall(Method method)
if (method.HasIndirectReturnTypeParameter)
{
var retParam = method.Parameters.First(p => p.Kind == ParameterKind.IndirectReturnType);
TypePrinter.PushContext(TypePrinterContextKind.Native);
WriteLine("*({0}*) {1} = {2};",
method.OriginalReturnType.Visit(TypePrinter), retParam.Name, marshal.Context.Return);
TypePrinter.PopContext();
TypePrinter.PrintNative(method.OriginalReturnType),
retParam.Name, marshal.Context.Return);
}
else
{
@@ -1924,9 +1910,7 @@ private void GenerateDisposeMethods(Class @class)
WriteLine($"{printedClass}{printedClass.NameSuffix} {Helpers.DummyIdentifier};");
WriteLine("NativeToManagedMap.TryRemove({0}, out {1});",
Helpers.InstanceIdentifier, Helpers.DummyIdentifier);
TypePrinter.PushContext(TypePrinterContextKind.Native);
var classInternal = @class.Visit(TypePrinter);
TypePrinter.PopContext();
var classInternal = TypePrinter.PrintNative(@class);
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{
if (Context.ParserOptions.IsMicrosoftAbi)
@@ -2062,9 +2046,7 @@ private void GenerateNativeConstructor(Class @class)
}
else
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
WriteLine($"{Helpers.InstanceField} = *({@class.Visit(TypePrinter)}*) native;");
TypePrinter.PopContext();
WriteLine($"{Helpers.InstanceField} = *({TypePrinter.PrintNative(@class)}*) native;");
}
WriteCloseBraceIndent();
@@ -2073,9 +2055,7 @@ private void GenerateNativeConstructor(Class @class)
public void GenerateNativeConstructorByValue(Class @class, string returnType)
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
var @internal = (@class.IsAbstractImpl ? @class.BaseClass : @class).Visit(TypePrinter);
TypePrinter.PopContext();
var @internal = TypePrinter.PrintNative(@class.IsAbstractImpl ? @class.BaseClass : @class);
if (!@class.IsAbstractImpl)
{
@@ -2101,11 +2081,9 @@ public void GenerateNativeConstructorByValue(Class @class, string returnType)
{
// Allocate memory for a new native object and call the ctor.
WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));");
TypePrinter.PushContext(TypePrinterContextKind.Native);
WriteLine($"{@class.Visit(TypePrinter)}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new global::System.IntPtr(&native));",
@class.Visit(TypePrinter),
GetFunctionNativeIdentifier(copyCtorMethod));
TypePrinter.PopContext();
var printed = TypePrinter.PrintNative(@class);
WriteLine($"{printed}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new global::System.IntPtr(&native));",
printed, GetFunctionNativeIdentifier(copyCtorMethod));
WriteLine("return ret.ToPointer();");
}
else
@@ -2420,10 +2398,8 @@ private void GenerateEqualsAndGetHashCode(Function method, Class @class)
{
WriteLine("if ({0} == global::System.IntPtr.Zero)", Helpers.InstanceIdentifier);
WriteLineIndent("return global::System.IntPtr.Zero.GetHashCode();");
TypePrinter.PushContext(TypePrinterContextKind.Native);
WriteLine($@"return (*({@class.Visit(TypePrinter)}*) {
WriteLine($@"return (*({TypePrinter.PrintNative(@class)}*) {
Helpers.InstanceIdentifier}).GetHashCode();");
TypePrinter.PopContext();
}
else
{
@@ -2544,9 +2520,8 @@ private void GenerateOperator(Method method)
private void GenerateClassConstructor(Method method, Class @class)
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
var @internal = (@class.IsAbstractImpl ? @class.BaseClass : @class).Visit(TypePrinter);
TypePrinter.PopContext();
var @internal = TypePrinter.PrintNative(
@class.IsAbstractImpl ? @class.BaseClass : @class);
WriteLine($"{Helpers.InstanceIdentifier} = Marshal.AllocHGlobal(sizeof({@internal}));");
WriteLine($"{Helpers.OwnsNativeInstanceIdentifier} = true;");
WriteLine($"NativeToManagedMap[{Helpers.InstanceIdentifier}] = this;");
@@ -2557,9 +2532,7 @@ private void GenerateClassConstructor(Method method, Class @class)
GenerateInternalFunctionCall(method);
else
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
var classInternal = @class.Visit(TypePrinter);
TypePrinter.PopContext();
var classInternal = TypePrinter.PrintNative(@class);
WriteLine($@"*(({classInternal}*) {Helpers.InstanceIdentifier}) = *(({
classInternal}*) {method.Parameters[0].Name}.{Helpers.InstanceIdentifier});");
}
@@ -2583,12 +2556,8 @@ private void GenerateClassConstructor(Method method, Class @class)
var @class = function.Namespace as Class;
string @internal = Helpers.InternalStruct;
if (@class != null && @class is ClassTemplateSpecialization)
{
TypePrinter.PushContext(TypePrinterContextKind.Native);
@internal = @class.Visit(TypePrinter).Type;
TypePrinter.PopContext();
}
if (@class is ClassTemplateSpecialization)
@internal = TypePrinter.PrintNative(@class).Type;
var nativeFunction = GetFunctionNativeIdentifier(function);
var functionName = $"{@internal}.{nativeFunction}";
@@ -2646,9 +2615,8 @@ private void GenerateClassConstructor(Method method, Class @class)
if (construct == null)
{
var @class = retClass.OriginalClass ?? retClass;
TypePrinter.PushContext(TypePrinterContextKind.Native);
WriteLine($"var {Helpers.ReturnIdentifier} = new {@class.Visit(TypePrinter)}();");
TypePrinter.PopContext();
WriteLine($@"var {Helpers.ReturnIdentifier} = new {
TypePrinter.PrintNative(@class)}();");
}
else
{
@@ -731,8 +731,6 @@ private static string GetParameterUsage(ParameterUsage usage)
}
}
private CSharpExpressionPrinter expressionPrinter => new CSharpExpressionPrinter(this);
public override TypePrinterResult VisitFieldDecl(Field field)
{
var cSharpSourcesDummy = new CSharpSources(Context, new List<TranslationUnit>());
@@ -755,5 +753,31 @@ public override TypePrinterResult VisitFieldDecl(Field field)
return returnTypePrinter;
}
public TypePrinterResult PrintNative(Declaration declaration)
{
PushContext(TypePrinterContextKind.Native);
var typePrinterResult = declaration.Visit(this);
PopContext();
return typePrinterResult;
}
public TypePrinterResult PrintNative(Type type)
{
PushContext(TypePrinterContextKind.Native);
var typePrinterResult = type.Visit(this);
PopContext();
return typePrinterResult;
}
public TypePrinterResult PrintNative(QualifiedType type)
{
PushContext(TypePrinterContextKind.Native);
var typePrinterResult = type.Visit(this);
PopContext();
return typePrinterResult;
}
private CSharpExpressionPrinter expressionPrinter => new CSharpExpressionPrinter(this);
}
}
@@ -63,10 +63,8 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
var type = ctx.Parameter.Type.Desugar();
ClassTemplateSpecialization basicString = GetBasicString(type);
var typePrinter = new CSharpTypePrinter(ctx.Context);
typePrinter.PushContext(TypePrinterContextKind.Native);
if (!ctx.Parameter.Type.Desugar().IsAddress())
ctx.Return.Write($"*({basicString.Visit(typePrinter)}*) ");
typePrinter.PopContext();
ctx.Return.Write($"*({typePrinter.PrintNative(basicString)}*) ");
var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First(
a => a.IsDependent && a.TranslationUnit.IsSystemHeader);
var allocatorChar = allocator.Specializations.First(s => !s.Ignore);

0 comments on commit 2af1af6

Please sign in to comment.