Browse Source

Fixed handling of primitive pointer types.

pull/225/head
Elias Holzer 11 years ago
parent
commit
d8b855bfe6
  1. 28
      src/AST/TypeExtensions.cs
  2. 4
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 18
      src/Generator/Generators/CLI/CLITypePrinter.cs
  4. 22
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  5. 10
      tests/Basic/Basic.Tests.cs
  6. 5
      tests/Basic/Basic.cpp
  7. 6
      tests/Basic/Basic.h

28
src/AST/TypeExtensions.cs

@ -155,5 +155,33 @@ @@ -155,5 +155,33 @@
return t;
}
public static Type GetFinalPointee(this PointerType pointer)
{
var pointee = pointer.Pointee;
while (pointee.IsPointer())
{
var p = pointee as PointerType;
if (p != null)
pointee = p.Pointee;
else
return GetFinalPointee(pointee as MemberPointerType);
}
return pointee;
}
public static Type GetFinalPointee(this MemberPointerType pointer)
{
var pointee = pointer.Pointee;
while (pointee.IsPointer())
{
var p = pointee as MemberPointerType;
if (p != null)
pointee = p.Pointee;
else
return GetFinalPointee(pointee as PointerType);
}
return pointee;
}
}
}

4
src/Generator/Generators/CLI/CLIMarshal.cs

@ -429,8 +429,8 @@ namespace CppSharp.Generators.CLI @@ -429,8 +429,8 @@ namespace CppSharp.Generators.CLI
return pointee.Visit(this, quals);
}
PrimitiveType primitive;
if (pointee.IsPrimitiveType(out primitive))
var finalPointee = pointer.GetFinalPointee();
if (finalPointee.IsPrimitiveType())
{
var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
var cppTypeName = pointer.Visit(cppTypePrinter, quals);

18
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -142,14 +142,22 @@ namespace CppSharp.Generators.CLI @@ -142,14 +142,22 @@ namespace CppSharp.Generators.CLI
return "System::String^";
}
PrimitiveType primitive;
if (pointee.Desugar().IsPrimitiveType(out primitive))
// From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
// Any of the following types may be a pointer type:
// * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
// * Any enum type.
// * Any pointer type.
// * Any user-defined struct type that contains fields of unmanaged types only.
var finalPointee = pointer.GetFinalPointee();
if (finalPointee.IsPrimitiveType())
{
// Skip one indirection if passed by reference
var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut))
return VisitPrimitiveType(primitive);
if (param != null && (param.IsOut || param.IsInOut)
&& pointee == finalPointee)
return pointee.Visit(this, quals);
return VisitPrimitiveType(primitive, quals) + "*";
return pointee.Visit(this, quals) + "*";
}
return pointee.Visit(this, quals);

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

@ -208,21 +208,29 @@ namespace CppSharp.Generators.CSharp @@ -208,21 +208,29 @@ namespace CppSharp.Generators.CSharp
if (IsConstCharString(pointer))
return isManagedContext ? "string" : "global::System.IntPtr";
PrimitiveType primitive;
var desugared = pointee.Desugar();
if (desugared.IsPrimitiveType(out primitive))
// From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
// Any of the following types may be a pointer type:
// * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
// * Any enum type.
// * Any pointer type.
// * Any user-defined struct type that contains fields of unmanaged types only.
var finalPointee = pointer.GetFinalPointee();
if (finalPointee.IsPrimitiveType())
{
if (isManagedContext && Context.Parameter != null &&
(Context.Parameter.IsOut || Context.Parameter.IsInOut))
return VisitPrimitiveType(primitive, quals);
// Skip one indirection if passed by reference
var param = Context.Parameter;
if (isManagedContext && param != null && (param.IsOut || param.IsInOut)
&& pointee == finalPointee)
return pointee.Visit(this, quals);
if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate)
return "global::System.IntPtr";
return VisitPrimitiveType(primitive, quals) + "*";
return pointee.Visit(this, quals) + "*";
}
Class @class;
var desugared = pointee.Desugar();
if ((desugared.IsDependent || desugared.IsTagDecl(out @class))
&& ContextKind == CSharpTypePrinterContextKind.Native)
{

10
tests/Basic/Basic.Tests.cs

@ -23,6 +23,16 @@ public class BasicTests : GeneratorTestFixture @@ -23,6 +23,16 @@ public class BasicTests : GeneratorTestFixture
Assert.That(hello.AddFooPtr(foo), Is.EqualTo(11));
Assert.That(hello.AddFooPtr(foo), Is.EqualTo(11));
Assert.That(hello.AddFooRef(foo), Is.EqualTo(11));
unsafe
{
var pointer = foo.SomePointer;
var pointerPointer = foo.SomePointerPointer;
for (int i = 0; i < 4; i++)
{
Assert.AreEqual(i, pointer[i]);
Assert.AreEqual(i, (*pointerPointer)[i]);
}
}
var bar = new Bar { A = 4, B = 7 };
Assert.That(hello.AddBar(bar), Is.EqualTo(11));

5
tests/Basic/Basic.cpp

@ -2,6 +2,11 @@ @@ -2,6 +2,11 @@
Foo::Foo()
{
auto p = new int[4];
for (int i = 0; i < 4; i++)
p[i] = i;
SomePointer = p;
SomePointerPointer = &SomePointer;
}
const char* Foo::GetANSI()

6
tests/Basic/Basic.h

@ -18,7 +18,11 @@ public: @@ -18,7 +18,11 @@ public:
// TODO: VC++ does not support char16
// char16 chr16;
float nested_array[2][2];
// Not properly handled yet - ignore
float nested_array[2][2];
// Primitive pointer types
int* SomePointer;
int** SomePointerPointer;
};
struct DLL_API Bar

Loading…
Cancel
Save