Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void WriteCustomAttribute(string attribute, Action callback = null)
{
AddUsingDirective("System.ComponentModel");
}
else if (attribute.StartsWith("Guid(") || attribute.StartsWith("Optional, DefaultParameterValue("))
else if (attribute.StartsWith("Guid(")|| attribute.Equals("Optional") || attribute.StartsWith("Optional, DefaultParameterValue("))
{
AddUsingDirective("System.Runtime.InteropServices");
}
Expand Down
209 changes: 127 additions & 82 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Large diffs are not rendered by default.

48 changes: 40 additions & 8 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1596,17 +1596,46 @@ private void VisitLabelStmt(LabelStmt labelStmt)
private void VisitMemberExpr(MemberExpr memberExpr)
{
var outputBuilder = StartCSharpCode();
if (!memberExpr.IsImplicitAccess)
var isForDerivedType = false;

if ((memberExpr.Base is ImplicitCastExpr implicitCastExpr) && (implicitCastExpr.CastKind is CX_CastKind.CX_CK_DerivedToBase or CX_CastKind.CX_CK_DerivedToBaseMemberPointer or CX_CastKind.CX_CK_UncheckedDerivedToBase))
{
if (memberExpr.MemberDecl is CXXMethodDecl cxxMethodDecl)
{
isForDerivedType = (_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != cxxMethodDecl.Parent) && HasField(cxxMethodDecl.Parent);
}
else if (memberExpr.MemberDecl is FieldDecl fieldDecl)
{
isForDerivedType = (_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != fieldDecl.Parent);
}
}

if (!memberExpr.IsImplicitAccess || isForDerivedType)
{
var memberExprBase = memberExpr.Base;
var memberExprBase = memberExpr.Base.IgnoreParens.IgnoreImplicit;

Visit(memberExprBase);
if (isForDerivedType)
{
outputBuilder.Write("Base");
}
else
{
Visit(memberExprBase);
}

memberExprBase = memberExprBase.IgnoreParens;
var type = null as Type;

var type = memberExprBase is CXXThisExpr
? null
: memberExprBase is DeclRefExpr declRefExpr ? declRefExpr.Decl.Type.CanonicalType : memberExpr.Base.Type.CanonicalType;
if (!IsStmtAsWritten<CXXThisExpr>(memberExprBase, out _, removeParens: true))
{
if (memberExprBase is DeclRefExpr declRefExpr)
{
type = declRefExpr.Decl.Type.CanonicalType;
}
else
{
type = memberExpr.Base.Type.CanonicalType;
}
}

if (type is not null and (PointerType or ReferenceType))
{
Expand Down Expand Up @@ -2398,7 +2427,6 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
{
AddDiagnostic(DiagnosticLevel.Error, $"Unsupported callee declaration: '{calleeDecl?.DeclKindName}'. Generated bindings may be incomplete.", calleeDecl);
}

}
else if (IsPrevContextStmt<Expr>(out var expr, out _))
{
Expand All @@ -2408,6 +2436,10 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
{
parentType = typeDecl.TypeForDecl.CanonicalType;
}
else if (IsPrevContextDecl<ValueDecl>(out var valueDecl, out _))
{
parentType = valueDecl.Type.CanonicalType;
}

var needsCast = false;
var typeName = GetRemappedTypeName(unaryExprOrTypeTraitExpr, context: null, argumentType, out _);
Expand Down
181 changes: 132 additions & 49 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod(MyStruct* pThis);
Expand All @@ -192,7 +192,7 @@ public int MyInt32Method()
return 0;
}}

public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -692,7 +692,7 @@ static int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod();
Expand All @@ -702,7 +702,7 @@ public static int MyInt32Method()
return 0;
}}

public static unsafe void* MyVoidStarMethod()
public static void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -759,9 +759,9 @@ protected override Task UnsafeDoesNotImpactDllImportTestImpl()

namespace ClangSharp.Test
{
public partial struct MyStruct
public unsafe partial struct MyStruct
{
public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,9 +734,9 @@ public partial struct MyStruct1B
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down Expand Up @@ -789,9 +789,9 @@ public partial struct MyStruct1B
[NativeInheritance(""MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod(MyStruct* pThis);
Expand All @@ -192,7 +192,7 @@ public int MyInt32Method()
return 0;
}}

public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -692,7 +692,7 @@ static int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod();
Expand All @@ -702,7 +702,7 @@ public static int MyInt32Method()
return 0;
}}

public static unsafe void* MyVoidStarMethod()
public static void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -759,9 +759,9 @@ protected override Task UnsafeDoesNotImpactDllImportTestImpl()

namespace ClangSharp.Test
{
public partial struct MyStruct
public unsafe partial struct MyStruct
{
public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,9 +738,9 @@ public partial struct MyStruct1B
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down Expand Up @@ -793,9 +793,9 @@ public partial struct MyStruct1B
[NativeInheritance(""MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod(MyStruct* pThis);
Expand All @@ -192,7 +192,7 @@ public int MyInt32Method()
return 0;
}}

public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -654,7 +654,7 @@ static int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod();
Expand All @@ -664,7 +664,7 @@ public static int MyInt32Method()
return 0;
}}

public static unsafe void* MyVoidStarMethod()
public static void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -721,9 +721,9 @@ protected override Task UnsafeDoesNotImpactDllImportTestImpl()

namespace ClangSharp.Test
{
public partial struct MyStruct
public unsafe partial struct MyStruct
{
public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,9 +742,9 @@ public partial struct MyStruct1B
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down Expand Up @@ -797,9 +797,9 @@ public partial struct MyStruct1B
[NativeInheritance(""MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod(MyStruct* pThis);
Expand All @@ -192,7 +192,7 @@ public int MyInt32Method()
return 0;
}}

public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -654,7 +654,7 @@ static int MyInt32Method()

namespace ClangSharp.Test
{{
public partial struct MyStruct
public unsafe partial struct MyStruct
{{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
public static extern void MyVoidMethod();
Expand All @@ -664,7 +664,7 @@ public static int MyInt32Method()
return 0;
}}

public static unsafe void* MyVoidStarMethod()
public static void* MyVoidStarMethod()
{{
return null;
}}
Expand Down Expand Up @@ -721,9 +721,9 @@ protected override Task UnsafeDoesNotImpactDllImportTestImpl()

namespace ClangSharp.Test
{
public partial struct MyStruct
public unsafe partial struct MyStruct
{
public unsafe void* MyVoidStarMethod()
public void* MyVoidStarMethod()
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,9 +746,9 @@ public partial struct MyStruct1B
[NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down Expand Up @@ -801,9 +801,9 @@ public partial struct MyStruct1B
[NativeInheritance(""MyStruct1B"")]
public partial struct MyStruct2
{
public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
public MyStruct1A Base;

public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
public MyStruct1B Base;

public int z;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ int MyInt32Method()
var expectedOutputContents = $@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
<bindings>
<namespace name=""ClangSharp.Test"">
<struct name=""MyStruct"" access=""public"">
<struct name=""MyStruct"" access=""public"" unsafe=""true"">
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""ThisCall"" entrypoint=""{entryPoint}"" static=""true"">
<type>void</type>
<param name=""pThis"">
Expand Down Expand Up @@ -845,7 +845,7 @@ static int MyInt32Method()
var expectedOutputContents = $@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
<bindings>
<namespace name=""ClangSharp.Test"">
<struct name=""MyStruct"" access=""public"">
<struct name=""MyStruct"" access=""public"" unsafe=""true"">
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""Cdecl"" entrypoint=""{entryPoint}"" static=""true"">
<type>void</type>
</function>
Expand Down Expand Up @@ -912,7 +912,7 @@ protected override Task UnsafeDoesNotImpactDllImportTestImpl()
var expectedOutputContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
<bindings>
<namespace name=""ClangSharp.Test"">
<struct name=""MyStruct"" access=""public"">
<struct name=""MyStruct"" access=""public"" unsafe=""true"">
<function name=""MyVoidStarMethod"" access=""public"" unsafe=""true"">
<type>void*</type>
<code>return null;</code>
Expand Down
Loading