Skip to content

Commit 93db16d

Browse files
Merge pull request #309 from tannergooding/main
Ensure that non-virtual C++ instance methods without a body have an inserted parameter for pThis
2 parents 875efb3 + 467f4b7 commit 93db16d

File tree

10 files changed

+93
-13
lines changed

10 files changed

+93
-13
lines changed

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,16 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
482482

483483
var cxxMethodDecl = functionDecl as CXXMethodDecl;
484484
var body = functionDecl.Body;
485+
var hasBody = body is not null;
485486

486-
var isVirtual = (cxxMethodDecl != null) && cxxMethodDecl.IsVirtual;
487+
var isCxxMethodDecl = cxxMethodDecl is not null;
488+
var isVirtual = isCxxMethodDecl && cxxMethodDecl.IsVirtual;
487489
var escapedName = isVirtual ? PrefixAndStripName(name, GetOverloadIndex(cxxMethodDecl)) : EscapeAndStripName(name);
488490

489491
var returnType = functionDecl.ReturnType;
490492
var returnTypeName = GetRemappedTypeName(functionDecl, cxxRecordDecl, returnType, out var nativeTypeName);
491493

492-
if ((isVirtual || (body is null)) && (returnTypeName == "bool"))
494+
if ((isVirtual || !hasBody) && (returnTypeName == "bool"))
493495
{
494496
// bool is not blittable, so we shouldn't use it for P/Invoke signatures
495497
returnTypeName = "byte";
@@ -499,15 +501,15 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
499501
var type = functionDecl.Type;
500502
var callingConventionName = GetCallingConvention(functionDecl, cxxRecordDecl, type);
501503

502-
var isDllImport = body is null && !isVirtual;
504+
var isDllImport = !hasBody && !isVirtual;
503505
var entryPoint = "";
504506

505507
if (isDllImport)
506508
{
507509
entryPoint = functionDecl.IsExternC ? GetCursorName(functionDecl) : functionDecl.Handle.Mangling.CString;
508510
}
509511

510-
var needsReturnFixup = isVirtual && NeedsReturnFixup(cxxMethodDecl);
512+
var needsReturnFixup = isCxxMethodDecl && NeedsReturnFixup(cxxMethodDecl);
511513

512514
var desc = new FunctionOrDelegateDesc {
513515
AccessSpecifier = accessSppecifier,
@@ -521,8 +523,8 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
521523
IsDllImport = isDllImport,
522524
HasFnPtrCodeGen = !_config.ExcludeFnptrCodegen,
523525
SetLastError = GetSetLastError(functionDecl),
524-
IsCxx = cxxMethodDecl is not null,
525-
IsStatic = isDllImport || (cxxMethodDecl?.IsStatic ?? true),
526+
IsCxx = isCxxMethodDecl,
527+
IsStatic = isDllImport || !isCxxMethodDecl || cxxMethodDecl.IsStatic,
526528
NeedsNewKeyword = NeedsNewKeyword(escapedName, functionDecl.Parameters),
527529
IsUnsafe = IsUnsafe(functionDecl),
528530
IsCtxCxxRecord = cxxRecordDecl is not null,
@@ -531,7 +533,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
531533
ReturnType = needsReturnFixup ? $"{returnTypeName}*" : returnTypeName,
532534
IsCxxConstructor = functionDecl is CXXConstructorDecl,
533535
Location = functionDecl.Location,
534-
HasBody = body is not null,
536+
HasBody = hasBody,
535537
WriteCustomAttrs = static context => {
536538
(var functionDecl, var outputBuilder, var generator) = ((FunctionDecl, IOutputBuilder, PInvokeGenerator))context;
537539

@@ -552,7 +554,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
552554

553555
_outputBuilder.BeginFunctionInnerPrototype(escapedName);
554556

555-
if (isVirtual)
557+
if (isVirtual || (isCxxMethodDecl && !hasBody && cxxMethodDecl.IsInstance))
556558
{
557559
Debug.Assert(cxxRecordDecl != null);
558560

@@ -593,7 +595,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
593595

594596
_outputBuilder.EndFunctionInnerPrototype();
595597

596-
if ((body is not null) && !isVirtual)
598+
if (hasBody && !isVirtual)
597599
{
598600
var firstCtorInitializer = functionDecl.Parameters.Any() ? (functionDecl.CursorChildren.IndexOf(functionDecl.Parameters.Last()) + 1) : 0;
599601
var lastCtorInitializer = (functionDecl.Body != null) ? functionDecl.CursorChildren.IndexOf(functionDecl.Body) : functionDecl.CursorChildren.Count;
@@ -3406,6 +3408,26 @@ private bool IsConstant(string targetTypeName, Expr initExpr)
34063408

34073409
case CX_StmtClass.CX_StmtClass_CallExpr:
34083410
{
3411+
var callExpr = (CallExpr)initExpr;
3412+
3413+
if (callExpr.DirectCallee.IsInlined)
3414+
{
3415+
var evaluateResult = callExpr.Handle.Evaluate;
3416+
3417+
switch (evaluateResult.Kind)
3418+
{
3419+
case CXEvalResultKind.CXEval_Int:
3420+
{
3421+
return true;
3422+
}
3423+
3424+
case CXEvalResultKind.CXEval_Float:
3425+
{
3426+
return true;
3427+
}
3428+
}
3429+
}
3430+
34093431
return false;
34103432
}
34113433

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections.Generic;
5+
using System.Diagnostics;
56
using System.Linq;
67
using System.Runtime.CompilerServices;
78
using System.Text;
@@ -68,6 +69,51 @@ private void VisitCallExpr(CallExpr callExpr)
6869
var outputBuilder = StartCSharpCode();
6970
var calleeDecl = callExpr.CalleeDecl;
7071

72+
if (callExpr.DirectCallee.IsInlined)
73+
{
74+
var evalResult = callExpr.Handle.Evaluate;
75+
var canonicalType = callExpr.Type.CanonicalType;
76+
77+
switch (evalResult.Kind)
78+
{
79+
case CXEvalResultKind.CXEval_Int:
80+
{
81+
if (canonicalType.Handle.IsUnsigned)
82+
{
83+
outputBuilder.Write(evalResult.AsUnsigned);
84+
}
85+
else
86+
{
87+
outputBuilder.Write(evalResult.AsLongLong);
88+
}
89+
90+
StopCSharpCode();
91+
return;
92+
}
93+
94+
case CXEvalResultKind.CXEval_Float:
95+
{
96+
if (canonicalType.Kind == CXTypeKind.CXType_Float)
97+
{
98+
outputBuilder.Write((float)evalResult.AsDouble);
99+
}
100+
else
101+
{
102+
outputBuilder.Write(evalResult.AsDouble);
103+
}
104+
105+
StopCSharpCode();
106+
return;
107+
}
108+
109+
case CXEvalResultKind.CXEval_StrLiteral:
110+
{
111+
AddDiagnostic(DiagnosticLevel.Info, "Possible string constant");
112+
break;
113+
}
114+
}
115+
}
116+
71117
if (calleeDecl is null)
72118
{
73119
Visit(callExpr.Callee);

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace ClangSharp.Test
185185
public partial struct MyStruct
186186
{{
187187
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
188-
public static extern void MyVoidMethod();
188+
public static extern void MyVoidMethod(MyStruct* pThis);
189189
190190
public int MyInt32Method()
191191
{{

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace ClangSharp.Test
185185
public partial struct MyStruct
186186
{{
187187
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
188-
public static extern void MyVoidMethod();
188+
public static extern void MyVoidMethod(MyStruct* pThis);
189189
190190
public int MyInt32Method()
191191
{{

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace ClangSharp.Test
185185
public partial struct MyStruct
186186
{{
187187
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
188-
public static extern void MyVoidMethod();
188+
public static extern void MyVoidMethod(MyStruct* pThis);
189189
190190
public int MyInt32Method()
191191
{{

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace ClangSharp.Test
185185
public partial struct MyStruct
186186
{{
187187
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)]
188-
public static extern void MyVoidMethod();
188+
public static extern void MyVoidMethod(MyStruct* pThis);
189189
190190
public int MyInt32Method()
191191
{{

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ int MyInt32Method()
226226
<struct name=""MyStruct"" access=""public"">
227227
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""ThisCall"" entrypoint=""{entryPoint}"" static=""true"">
228228
<type>void</type>
229+
<param name=""pThis"">
230+
<type>MyStruct*</type>
231+
</param>
229232
</function>
230233
<function name=""MyInt32Method"" access=""public"">
231234
<type>int</type>

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ int MyInt32Method()
226226
<struct name=""MyStruct"" access=""public"">
227227
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""ThisCall"" entrypoint=""{entryPoint}"" static=""true"">
228228
<type>void</type>
229+
<param name=""pThis"">
230+
<type>MyStruct*</type>
231+
</param>
229232
</function>
230233
<function name=""MyInt32Method"" access=""public"">
231234
<type>int</type>

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ int MyInt32Method()
226226
<struct name=""MyStruct"" access=""public"">
227227
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""ThisCall"" entrypoint=""{entryPoint}"" static=""true"">
228228
<type>void</type>
229+
<param name=""pThis"">
230+
<type>MyStruct*</type>
231+
</param>
229232
</function>
230233
<function name=""MyInt32Method"" access=""public"">
231234
<type>int</type>

tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ int MyInt32Method()
226226
<struct name=""MyStruct"" access=""public"">
227227
<function name=""MyVoidMethod"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""ThisCall"" entrypoint=""{entryPoint}"" static=""true"">
228228
<type>void</type>
229+
<param name=""pThis"">
230+
<type>MyStruct*</type>
231+
</param>
229232
</function>
230233
<function name=""MyInt32Method"" access=""public"">
231234
<type>int</type>

0 commit comments

Comments
 (0)