Browse Source

Fixed the ambiguity in the C++/CLI branch when a native ctor takes anything mapped to IntPtr.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/359/head
Dimitar Dobrev 11 years ago
parent
commit
f1c0d7a82a
  1. 1
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 2
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 33
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  4. 9
      src/Generator/Generators/CLI/CLITypePrinter.cs
  5. 6
      tests/Basic/Basic.Tests.cs
  6. 15
      tests/Basic/Basic.cpp
  7. 16
      tests/Basic/Basic.h
  8. 8
      tests/CSharpTemp/CSharpTemp.Tests.cs
  9. 23
      tests/CSharpTemp/CSharpTemp.cpp
  10. 13
      tests/CSharpTemp/CSharpTemp.h

1
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -368,7 +368,6 @@ namespace CppSharp.Generators.CLI
// Output a default constructor that takes the native pointer. // Output a default constructor that takes the native pointer.
WriteLine("{0}({1} native);", @class.Name, nativeType); WriteLine("{0}({1} native);", @class.Name, nativeType);
WriteLine("{0}({1} native);", @class.Name, "System::IntPtr");
foreach (var ctor in @class.Constructors) foreach (var ctor in @class.Constructors)
{ {

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

@ -83,7 +83,7 @@ namespace CppSharp.Generators.CLI
if (pointee.IsPrimitiveType(PrimitiveType.Void)) if (pointee.IsPrimitiveType(PrimitiveType.Void))
{ {
Context.Return.Write(Context.ReturnVarName); Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName);
return true; return true;
} }

33
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -192,8 +192,7 @@ namespace CppSharp.Generators.CLI
return; return;
// Output a default constructor that takes the native pointer. // Output a default constructor that takes the native pointer.
GenerateClassConstructor(@class, isIntPtr: false); GenerateClassConstructor(@class);
GenerateClassConstructor(@class, isIntPtr: true);
if (Options.GenerateFinalizers && @class.IsRefType) if (Options.GenerateFinalizers && @class.IsRefType)
{ {
@ -215,7 +214,7 @@ namespace CppSharp.Generators.CLI
foreach (var method in @class.Methods) foreach (var method in @class.Methods)
{ {
if (ASTUtils.CheckIgnoreMethod(method, this.Options)) if (ASTUtils.CheckIgnoreMethod(method, Options))
continue; continue;
// C++/CLI does not allow special member funtions for value types. // C++/CLI does not allow special member funtions for value types.
@ -611,25 +610,18 @@ namespace CppSharp.Generators.CLI
GeneratePropertySetter(variable, @class, variable.Name, variable.Type); GeneratePropertySetter(variable, @class, variable.Name, variable.Type);
} }
private void GenerateClassConstructor(Class @class, bool isIntPtr) private void GenerateClassConstructor(Class @class)
{ {
Write("{0}::{1}(", QualifiedIdentifier(@class), @class.Name); Write("{0}::{1}(", QualifiedIdentifier(@class), @class.Name);
var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName); var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName);
WriteLine("{0} native)", isIntPtr ? "System::IntPtr" : nativeType); WriteLine("{0} native)", nativeType);
var hasBase = GenerateClassConstructorBase(@class, isIntPtr); var hasBase = GenerateClassConstructorBase(@class);
WriteStartBraceIndent(); WriteStartBraceIndent();
var nativePtr = "native"; const string nativePtr = "native";
if (isIntPtr)
{
WriteLine("auto __native = (::{0}*)native.ToPointer();",
@class.QualifiedOriginalName);
nativePtr = "__native";
}
if (@class.IsRefType) if (@class.IsRefType)
{ {
@ -680,7 +672,7 @@ namespace CppSharp.Generators.CLI
} }
} }
private bool GenerateClassConstructorBase(Class @class, bool isIntPtr, Method method = null) private bool GenerateClassConstructorBase(Class @class, Method method = null)
{ {
var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsDeclared; var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsDeclared;
if (!hasBase) if (!hasBase)
@ -695,12 +687,9 @@ namespace CppSharp.Generators.CLI
// We cast the value to the base clas type since otherwise there // We cast the value to the base clas type since otherwise there
// could be ambiguous call to overloaded constructors. // could be ambiguous call to overloaded constructors.
if (!isIntPtr) var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
{ var nativeTypeName = baseClass.Visit(cppTypePrinter);
var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase); Write("({0}*)", nativeTypeName);
var nativeTypeName = baseClass.Visit(cppTypePrinter);
Write("({0}*)", nativeTypeName);
}
WriteLine("{0})", method != null ? "nullptr" : "native"); WriteLine("{0})", method != null ? "nullptr" : "native");
@ -727,7 +716,7 @@ namespace CppSharp.Generators.CLI
WriteLine(")"); WriteLine(")");
if (method.IsConstructor) if (method.IsConstructor)
GenerateClassConstructorBase(@class, isIntPtr: false, method: method); GenerateClassConstructorBase(@class, method: method);
WriteStartBraceIndent(); WriteStartBraceIndent();

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

@ -154,10 +154,15 @@ namespace CppSharp.Generators.CLI
{ {
// Skip one indirection if passed by reference // Skip one indirection if passed by reference
var param = Context.Parameter; var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut)) bool isRefParam = param != null && (param.IsOut || param.IsInOut);
if (isRefParam)
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
return pointee.Visit(this, quals) + "*"; if (pointee.IsPrimitiveType(PrimitiveType.Void))
return "::System::IntPtr";
var result = pointee.Visit(this, quals);
return !isRefParam && result == "::System::IntPtr" ? "void**" : result + "*";
} }
Enumeration @enum; Enumeration @enum;

6
tests/Basic/Basic.Tests.cs

@ -452,5 +452,11 @@ public class BasicTests : GeneratorTestFixture
for (int i = 0; i < foo.fixedArray.Length; i++) for (int i = 0; i < foo.fixedArray.Length; i++)
Assert.That(array[i], Is.EqualTo(foo.fixedArray[i])); Assert.That(array[i], Is.EqualTo(foo.fixedArray[i]));
} }
[Test]
public void TestInternalCtorAmbiguity()
{
new InvokesInternalCtorAmbiguity().InvokeInternalCtor();
}
} }

15
tests/Basic/Basic.cpp

@ -317,3 +317,18 @@ std::string HasStdString::testStdString(std::string s)
{ {
return s + "_test"; return s + "_test";
} }
InternalCtorAmbiguity::InternalCtorAmbiguity(void* param)
{
// cause a crash to indicate this is the incorrect ctor to invoke
throw;
}
InvokesInternalCtorAmbiguity::InvokesInternalCtorAmbiguity() : ptr(0)
{
}
InternalCtorAmbiguity* InvokesInternalCtorAmbiguity::InvokeInternalCtor()
{
return ptr;
}

16
tests/Basic/Basic.h

@ -30,6 +30,7 @@ public:
float B; float B;
IgnoredType ignoredType; IgnoredType ignoredType;
int fixedArray[3]; int fixedArray[3];
void* ptr;
const char* GetANSI(); const char* GetANSI();
// TODO: VC++ does not support char16 // TODO: VC++ does not support char16
@ -630,3 +631,18 @@ public:
std::string testStdString(std::string s); std::string testStdString(std::string s);
std::string s; std::string s;
}; };
class DLL_API InternalCtorAmbiguity
{
public:
InternalCtorAmbiguity(void* param);
};
class DLL_API InvokesInternalCtorAmbiguity
{
public:
InvokesInternalCtorAmbiguity();
InternalCtorAmbiguity* InvokeInternalCtor();
private:
InternalCtorAmbiguity* ptr;
};

8
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -164,12 +164,4 @@ public class CSharpTempTests : GeneratorTestFixture
Assert.AreEqual(q1.Array[i], q2.Array[i]); Assert.AreEqual(q1.Array[i], q2.Array[i]);
} }
} }
[Test]
public void TestInternalCtorAmbiguity()
{
using (new InternalCtorAmbiguity().InvokeInternalCtor())
{
}
}
} }

23
tests/CSharpTemp/CSharpTemp.cpp

@ -301,25 +301,4 @@ IgnoredType<int> PropertyWithIgnoredType::ignoredType()
void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value) void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value)
{ {
_ignoredType = value; _ignoredType = value;
} }
InternalCtorAmbiguity::InternalCtorAmbiguity() : copy(0)
{
}
InternalCtorAmbiguity::InternalCtorAmbiguity(void* param) : copy(0)
{
// cause a crash to indicate this is the incorrect ctor to invoke
throw;
}
InternalCtorAmbiguity* InternalCtorAmbiguity::InvokeInternalCtor()
{
return copy = new InternalCtorAmbiguity();
}
InternalCtorAmbiguity::~InternalCtorAmbiguity()
{
if (copy)
delete copy;
}

13
tests/CSharpTemp/CSharpTemp.h

@ -260,15 +260,4 @@ public:
void setIgnoredType(const IgnoredType<int>& value); void setIgnoredType(const IgnoredType<int>& value);
private: private:
IgnoredType<int> _ignoredType; IgnoredType<int> _ignoredType;
}; };
class DLL_API InternalCtorAmbiguity
{
public:
InternalCtorAmbiguity();
InternalCtorAmbiguity(void* param);
InternalCtorAmbiguity* InvokeInternalCtor();
~InternalCtorAmbiguity();
private:
InternalCtorAmbiguity* copy;
};
Loading…
Cancel
Save