Browse Source

Commented the pass about internal impls of abstract classes. Cosmetic fixes.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/53/head
Dimitar Dobrev 13 years ago
parent
commit
1c793ef589
  1. 25
      src/AST/Function.cs
  2. 9
      src/AST/Method.cs
  3. 35
      src/Generator/AST/VTables.cs
  4. 35
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  5. 24
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs

25
src/AST/Function.cs

@ -165,27 +165,30 @@ namespace CppSharp.AST @@ -165,27 +165,30 @@ namespace CppSharp.AST
public virtual QualifiedType GetFunctionType()
{
var functionType = new FunctionType();
functionType.CallingConvention = CallingConvention;
functionType.ReturnType = ReturnType;
var functionType = new FunctionType
{
CallingConvention = this.CallingConvention,
ReturnType = this.ReturnType
};
functionType.Parameters.AddRange(Parameters);
ReplaceIndirectReturnParamWithRegular(functionType);
var pointerType = new PointerType { QualifiedPointee = new QualifiedType(functionType) };
return new QualifiedType(pointerType);
}
private static void ReplaceIndirectReturnParamWithRegular(FunctionType functionType)
{
for (int i = functionType.Parameters.Count - 1; i >= 0; i--)
{
var parameter = functionType.Parameters[i];
if (parameter.Kind == ParameterKind.IndirectReturnType)
{
var retParam = new Parameter();
retParam.Name = parameter.Name;
var ptrType = new PointerType();
ptrType.QualifiedPointee = new QualifiedType(parameter.Type);
retParam.QualifiedType = new QualifiedType(ptrType);
var ptrType = new PointerType { QualifiedPointee = new QualifiedType(parameter.Type) };
var retParam = new Parameter { Name = parameter.Name, QualifiedType = new QualifiedType(ptrType) };
functionType.Parameters.RemoveAt(i);
functionType.Parameters.Insert(i, retParam);
}
}
var pointerType = new PointerType();
pointerType.QualifiedPointee = new QualifiedType(functionType);
return new QualifiedType(pointerType);
}
}
}

9
src/AST/Method.cs

@ -127,10 +127,11 @@ namespace CppSharp.AST @@ -127,10 +127,11 @@ namespace CppSharp.AST
{
FunctionType functionType;
qualifiedType.Type.IsPointerTo(out functionType);
var instance = new Parameter();
instance.Name = "instance";
instance.QualifiedType = new QualifiedType(
new BuiltinType(PrimitiveType.IntPtr));
var instance = new Parameter
{
Name = "instance",
QualifiedType = new QualifiedType(new BuiltinType(PrimitiveType.IntPtr))
};
functionType.Parameters.Insert(0, instance);
}
return qualifiedType;

35
src/Generator/AST/VTables.cs

@ -83,41 +83,18 @@ namespace CppSharp.AST @@ -83,41 +83,18 @@ namespace CppSharp.AST
throw new NotSupportedException();
}
public static string GetVirtualCallDelegate(INamedDecl method, Class @class,
bool is32Bit, out string delegateId)
public static int GetVTableIndex(INamedDecl method, Class @class)
{
var virtualCallBuilder = new StringBuilder();
virtualCallBuilder.AppendFormat(
"void* vtable = *((void**) {0}.ToPointer());",
Helpers.InstanceIdentifier);
virtualCallBuilder.AppendLine();
int i;
switch (@class.Layout.ABI)
{
case CppAbi.Microsoft:
i = (from table in @class.Layout.VFTables
let j = table.Layout.Components.FindIndex(m => m.Method == method)
where j >= 0
select j).First();
break;
return (from table in @class.Layout.VFTables
let j = table.Layout.Components.FindIndex(m => m.Method == method)
where j >= 0
select j).First();
default:
i = @class.Layout.Layout.Components.FindIndex(m => m.Method == method);
break;
return @class.Layout.Layout.Components.FindIndex(m => m.Method == method);
}
virtualCallBuilder.AppendFormat(
"void* slot = *((void**) vtable + {0} * {1});", i, is32Bit ? 4 : 8);
virtualCallBuilder.AppendLine();
string @delegate = method.Name + "Delegate";
delegateId = Generator.GeneratedIdentifier(@delegate);
virtualCallBuilder.AppendFormat(
"var {1} = ({0}) Marshal.GetDelegateForFunctionPointer(new IntPtr(slot), typeof({0}));",
@delegate, delegateId);
virtualCallBuilder.AppendLine();
return virtualCallBuilder.ToString();
}
}
}

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

@ -626,8 +626,7 @@ namespace CppSharp.Generators.CSharp @@ -626,8 +626,7 @@ namespace CppSharp.Generators.CSharp
Write(Helpers.GetAccess(@class));
Write("unsafe ");
if (Driver.Options.GenerateAbstractImpls &&
@class.IsAbstract)
if (Driver.Options.GenerateAbstractImpls && @class.IsAbstract)
Write("abstract ");
if (Options.GeneratePartialClasses)
@ -1365,8 +1364,7 @@ namespace CppSharp.Generators.CSharp @@ -1365,8 +1364,7 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Method);
string className = @class.Name;
string safeIdentifier = SafeIdentifier(className);
if (@class.Access == AccessSpecifier.Private &&
className.EndsWith("Internal"))
if (@class.Access == AccessSpecifier.Private && className.EndsWith("Internal"))
{
className = className.Substring(0,
safeIdentifier.LastIndexOf("Internal", StringComparison.Ordinal));
@ -1379,8 +1377,7 @@ namespace CppSharp.Generators.CSharp @@ -1379,8 +1377,7 @@ namespace CppSharp.Generators.CSharp
PopBlock(NewLineKind.BeforeNextBlock);
PushBlock(CSharpBlockKind.Method);
WriteLine("internal {0}({1}.Internal native)", safeIdentifier,
className);
WriteLine("internal {0}({1}.Internal native)", safeIdentifier, className);
WriteLineIndent(": this(&native)");
WriteStartBraceIndent();
WriteCloseBraceIndent();
@ -1574,10 +1571,34 @@ namespace CppSharp.Generators.CSharp @@ -1574,10 +1571,34 @@ namespace CppSharp.Generators.CSharp
private void GenerateVirtualTableFunctionCall(Function method, Class @class)
{
string delegateId;
Write(VTables.GetVirtualCallDelegate(method, @class, Driver.Options.Is32Bit, out delegateId));
Write(GetVirtualCallDelegate(method, @class, Driver.Options.Is32Bit, out delegateId));
GenerateFunctionCall(delegateId, method.Parameters, method);
}
public static string GetVirtualCallDelegate(INamedDecl method, Class @class,
bool is32Bit, out string delegateId)
{
var virtualCallBuilder = new StringBuilder();
virtualCallBuilder.AppendFormat("void* vtable = *((void**) {0}.ToPointer());",
Helpers.InstanceIdentifier);
virtualCallBuilder.AppendLine();
var i = VTables.GetVTableIndex(method, @class);
virtualCallBuilder.AppendFormat(
"void* slot = *((void**) vtable + {0} * {1});", i, is32Bit ? 4 : 8);
virtualCallBuilder.AppendLine();
string @delegate = method.Name + "Delegate";
delegateId = Generator.GeneratedIdentifier(@delegate);
virtualCallBuilder.AppendFormat(
"var {1} = ({0}) Marshal.GetDelegateForFunctionPointer(new IntPtr(slot), typeof({0}));",
@delegate, delegateId);
virtualCallBuilder.AppendLine();
return virtualCallBuilder.ToString();
}
private void GenerateOperator(Method method, Class @class)
{
if (method.IsSynthetized)

24
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -5,6 +5,11 @@ using CppSharp.Utils; @@ -5,6 +5,11 @@ using CppSharp.Utils;
namespace CppSharp.Passes
{
/// <summary>
/// This pass generates internal classes that implement abstract classes.
/// When the return type of a function is abstract, these internal classes provide -
/// since the real type cannot be resolved while binding - an allocatable class that supports proper polymorphism.
/// </summary>
public class GenerateAbstractImplementationsPass : TranslationUnitPass
{
private readonly List<Class> classes = new List<Class>();
@ -39,9 +44,12 @@ namespace CppSharp.Passes @@ -39,9 +44,12 @@ namespace CppSharp.Passes
foreach (var abstractMethod in abstractMethods)
{
internalImpl.Methods.Add(new Method(abstractMethod));
var @delegate = new TypedefDecl { Name = abstractMethod.Name + "Delegate" };
@delegate.QualifiedType = abstractMethod.GetFunctionType();
@delegate.IgnoreFlags = abstractMethod.IgnoreFlags;
var @delegate = new TypedefDecl
{
Name = abstractMethod.Name + "Delegate",
QualifiedType = abstractMethod.GetFunctionType(),
IgnoreFlags = abstractMethod.IgnoreFlags
};
internalImpl.Typedefs.Add(@delegate);
}
@ -59,10 +67,12 @@ namespace CppSharp.Passes @@ -59,10 +67,12 @@ namespace CppSharp.Passes
private static Class GetInternalImpl(Declaration @class)
{
var internalImpl = new Class();
internalImpl.Name = @class.Name + "Internal";
internalImpl.Access = AccessSpecifier.Private;
internalImpl.Namespace = @class.Namespace;
var internalImpl = new Class
{
Name = @class.Name + "Internal",
Access = AccessSpecifier.Private,
Namespace = @class.Namespace
};
var @base = new BaseClassSpecifier { Type = new TagType(@class) };
internalImpl.Bases.Add(@base);
return internalImpl;

Loading…
Cancel
Save