Browse Source

Decreased the pass for abstract impls in half.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/546/head
Dimitar Dobrev 10 years ago
parent
commit
9377845ba7
  1. 10
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 81
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs

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

@ -820,7 +820,7 @@ namespace CppSharp.Generators.CSharp @@ -820,7 +820,7 @@ namespace CppSharp.Generators.CSharp
if (function.SynthKind == FunctionSynthKind.AbstractImplCall)
{
string delegateId;
Write(GetAbstractCallDelegate(function, @class, out delegateId));
Write(GetAbstractCallDelegate(function, @class.BaseClass, out delegateId));
GenerateFunctionCall(delegateId, new List<Parameter> { param }, function);
}
else
@ -955,7 +955,7 @@ namespace CppSharp.Generators.CSharp @@ -955,7 +955,7 @@ namespace CppSharp.Generators.CSharp
WriteStartBraceIndent();
var method = function as Method;
if (method != null && method.SynthKind == FunctionSynthKind.AbstractImplCall)
GenerateAbstractImplCall(method, @class);
GenerateAbstractImplCall(method, @class.BaseClass);
else
GenerateInternalFunctionCall(function, function.Parameters, returnType.Type);
}
@ -2124,7 +2124,7 @@ namespace CppSharp.Generators.CSharp @@ -2124,7 +2124,7 @@ namespace CppSharp.Generators.CSharp
}
else if (method.SynthKind == FunctionSynthKind.AbstractImplCall)
{
GenerateAbstractImplCall(method, @class);
GenerateAbstractImplCall(method, @class.BaseClass);
}
else
{
@ -2264,9 +2264,9 @@ namespace CppSharp.Generators.CSharp @@ -2264,9 +2264,9 @@ namespace CppSharp.Generators.CSharp
out string delegateId)
{
var virtualCallBuilder = new StringBuilder();
var i = VTables.GetVTableIndex(function, @class);
var i = VTables.GetVTableIndex(function.OriginalFunction, @class);
virtualCallBuilder.AppendFormat("void* slot = *(void**) ((({0}.Internal*) {1})->vfptr0 + {2} * {3});",
@class.BaseClass.Name, Helpers.InstanceIdentifier, i, Driver.TargetInfo.PointerWidth / 8);
@class.Name, Helpers.InstanceIdentifier, i, Driver.TargetInfo.PointerWidth / 8);
virtualCallBuilder.AppendLine();
string @delegate = GetVTableMethodDelegateName(function.OriginalFunction);

81
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppAbi = CppSharp.Parser.AST.CppAbi;
namespace CppSharp.Passes
{
@ -53,7 +52,7 @@ namespace CppSharp.Passes @@ -53,7 +52,7 @@ namespace CppSharp.Passes
return @class.IsAbstract;
}
private Class AddInternalImplementation(Class @class)
private static Class AddInternalImplementation(Class @class)
{
var internalImpl = GetInternalImpl(@class);
@ -70,8 +69,7 @@ namespace CppSharp.Passes @@ -70,8 +69,7 @@ namespace CppSharp.Passes
SynthKind = FunctionSynthKind.AbstractImplCall
});
internalImpl.Layout = new ClassLayout(@class.Layout);
FillVTable(@class, abstractMethods, internalImpl);
internalImpl.Layout = @class.Layout;
return internalImpl;
}
@ -128,80 +126,5 @@ namespace CppSharp.Passes @@ -128,80 +126,5 @@ namespace CppSharp.Passes
return overriddenMethods;
}
private void FillVTable(Class @class, IList<Method> abstractMethods, Class internalImplementation)
{
switch (Driver.Options.Abi)
{
case CppAbi.Microsoft:
CreateVTableMS(@class, abstractMethods, internalImplementation);
break;
default:
CreateVTableItanium(@class, abstractMethods, internalImplementation);
break;
}
}
private static void CreateVTableMS(Class @class,
IList<Method> abstractMethods, Class internalImplementation)
{
var vtables = GetVTables(@class);
for (int i = 0; i < abstractMethods.Count; i++)
{
for (int j = 0; j < vtables.Count; j++)
{
var vTable = vtables[j];
var k = vTable.Layout.Components.FindIndex(v => v.Method == abstractMethods[i]);
if (k >= 0)
{
var vTableComponent = vTable.Layout.Components[k];
vTableComponent.Declaration = internalImplementation.Methods[i];
vTable.Layout.Components[k] = vTableComponent;
vtables[j] = vTable;
}
}
}
internalImplementation.Layout.VFTables.Clear();
internalImplementation.Layout.VFTables.AddRange(vtables);
}
private static void CreateVTableItanium(Class @class,
IList<Method> abstractMethods, Class internalImplementation)
{
var vtableComponents = GetVTableComponents(@class);
for (var i = 0; i < abstractMethods.Count; i++)
{
var j = vtableComponents.FindIndex(v => v.Method == abstractMethods[i]);
var vtableComponent = vtableComponents[j];
vtableComponent.Declaration = internalImplementation.Methods[i];
vtableComponents[j] = vtableComponent;
}
internalImplementation.Layout.Layout.Components.Clear();
internalImplementation.Layout.Layout.Components.AddRange(vtableComponents);
}
private static List<VTableComponent> GetVTableComponents(Class @class)
{
var vtableComponents = new List<VTableComponent>(
@class.Layout.Layout.Components);
foreach (var @base in @class.Bases)
vtableComponents.AddRange(GetVTableComponents(@base.Class));
return vtableComponents;
}
private static List<VFTableInfo> GetVTables(Class @class)
{
var vtables = new List<VFTableInfo>(
@class.Layout.VFTables);
foreach (var @base in @class.Bases)
vtables.AddRange(GetVTables(@base.Class));
return vtables;
}
}
}

Loading…
Cancel
Save