diff --git a/Directory.Build.props b/Directory.Build.props
index bb8873f0..b28c2c45 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -43,7 +43,7 @@
$(BaseArtifactsPath)pkg/$(Configuration)/
ClangSharp
11.0.0
- beta2
+ beta3
pr
diff --git a/README.md b/README.md
index 05ed8d7d..f8af2d6b 100644
--- a/README.md
+++ b/README.md
@@ -4,10 +4,10 @@ ClangSharp provides Clang bindings written in C#. It is self-hosted and auto-gen
| Job | Debug Status | Release Status |
| --- | ------------ | -------------- |
-| Windows x86 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) |
-| Windows x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) |
-| Ubuntu 18.04 x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) |
-| MacOS x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=master) |
+| Windows x86 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) |
+| Windows x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) |
+| Ubuntu 18.04 x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) |
+| MacOS x64 | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) | [](https://dev.azure.com/ms/ClangSharp/_build/latest?definitionId=155&branchName=main) |
A nuget package for the project is provided here: https://www.nuget.org/packages/clangsharp.
A .NET tool for the P/Invoke generator project is provided here: https://www.nuget.org/packages/ClangSharpPInvokeGenerator
@@ -93,7 +93,7 @@ dotnet tool install --global ClangSharpPInvokeGenerator --version 11.0.0-beta2
ClangSharpPInvokeGenerator @generate.rsp
```
-A response file allows you to specify and checkin the command line arguments in a text file, with one argument per line. For example: https://github.com/microsoft/ClangSharp/blob/master/sources/ClangSharpPInvokeGenerator/Properties/GenerateClang.rsp
+A response file allows you to specify and checkin the command line arguments in a text file, with one argument per line. For example: https://github.com/microsoft/ClangSharp/blob/main/sources/ClangSharpPInvokeGenerator/Properties/GenerateClang.rsp
At a minimum, the command line expects one or more input files (`-f`), an output namespace (`-n`), and an output location (`-o`). A typical response file may also specify explicit files to traverse, configuration options, name remappings, and other fixups.
The full set of available switches:
@@ -194,7 +194,11 @@ Options:
are commonly encountered for opaque handle like types such as HWND.
exclude-enum-operators Bindings for operators over enum types should not be generated. These are
largely unnecessary in C# as the operators are available by default.
+ exclude-fnptr-codegen Generated bindings for latest or preview codegen should not use function
+ pointers.
exclude-funcs-with-body Bindings for functions with bodies should not be generated.
+ preview-codegen-nint Generated bindings for latest or preview codegen should not use nint or
+ nuint.
exclude-using-statics-for-enums Enum usages should be fully qualified and should not include a
corresponding 'using static EnumName;'
@@ -209,12 +213,14 @@ Options:
generate-aggressive-inlining [MethodImpl(MethodImplOptions.AggressiveInlining)] should be added to
generated helper functions.
- generate-cpp-attributes A[CppAttributeList("")] should be generated to document the encountered C++
+ generate-cpp-attributes [CppAttributeList("")] should be generated to document the encountered C++
attributes.
generate-macro-bindings Bindings for macro-definitions should be generated. This currently only
works with value like macros and not function-like ones.
- generate-native-inheritance-attribute A[NativeInheritance("")] attribute should be generated to document the
+ generate-native-inheritance-attribute [NativeInheritance("")] attribute should be generated to document the
encountered C++ base type.
+ generate-vtbl-index-attribute [VtblIndex(#)] attribute should be generated to document the underlying
+ VTBL index for a helper method.
log-exclusions Alist of excluded declaration types should be generated. This will also log
if the exclusion was due to an exact or partial match.
@@ -222,11 +228,6 @@ Options:
identify missing remappings.
log-visited-files Alist of the visited files should be generated. This can help identify
traversal issues.
-
- preview-codegen-fnptr Generated bindings should use function pointers instead of IntPtr where
- possible.
- preview-codegen-nint Generated bindings should use nint and nuint instead of IntPtr and UIntPtr
- where possible.
```
## Spotlight
diff --git a/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x64/libClangSharp.runtime.freebsd.11-x64.nuspec b/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x64/libClangSharp.runtime.freebsd.11-x64.nuspec
index 97a3385e..cf8f9269 100644
--- a/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x64/libClangSharp.runtime.freebsd.11-x64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x64/libClangSharp.runtime.freebsd.11-x64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.freebsd.11-x64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
freebsd 11 x64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x86/libClangSharp.runtime.freebsd.11-x86.nuspec b/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x86/libClangSharp.runtime.freebsd.11-x86.nuspec
index 0be7b237..084d8be6 100644
--- a/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x86/libClangSharp.runtime.freebsd.11-x86.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.freebsd.11-x86/libClangSharp.runtime.freebsd.11-x86.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.freebsd.11-x86
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
freebsd 11 x86 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.linux-arm/libClangSharp.runtime.linux-arm.nuspec b/packages/libClangSharp/libClangSharp.runtime.linux-arm/libClangSharp.runtime.linux-arm.nuspec
index 258730ac..ac9e95f1 100644
--- a/packages/libClangSharp/libClangSharp.runtime.linux-arm/libClangSharp.runtime.linux-arm.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.linux-arm/libClangSharp.runtime.linux-arm.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.linux-arm
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
linux arm native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.linux-arm64/libClangSharp.runtime.linux-arm64.nuspec b/packages/libClangSharp/libClangSharp.runtime.linux-arm64/libClangSharp.runtime.linux-arm64.nuspec
index a218ae27..83aa70bd 100644
--- a/packages/libClangSharp/libClangSharp.runtime.linux-arm64/libClangSharp.runtime.linux-arm64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.linux-arm64/libClangSharp.runtime.linux-arm64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.linux-arm64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
linux arm64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.osx-x64/libClangSharp.runtime.osx-x64.nuspec b/packages/libClangSharp/libClangSharp.runtime.osx-x64/libClangSharp.runtime.osx-x64.nuspec
index 971bc1ef..3bf372c3 100644
--- a/packages/libClangSharp/libClangSharp.runtime.osx-x64/libClangSharp.runtime.osx-x64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.osx-x64/libClangSharp.runtime.osx-x64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.osx-x64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
osx x64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.ubuntu.18.04-x64/libClangSharp.runtime.ubuntu.18.04-x64.nuspec b/packages/libClangSharp/libClangSharp.runtime.ubuntu.18.04-x64/libClangSharp.runtime.ubuntu.18.04-x64.nuspec
index c489478c..12710ea4 100644
--- a/packages/libClangSharp/libClangSharp.runtime.ubuntu.18.04-x64/libClangSharp.runtime.ubuntu.18.04-x64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.ubuntu.18.04-x64/libClangSharp.runtime.ubuntu.18.04-x64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.ubuntu.18.04-x64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
ubuntu 18.04 x64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.ubuntu.20.04-x64/libClangSharp.runtime.ubuntu.20.04-x64.nuspec b/packages/libClangSharp/libClangSharp.runtime.ubuntu.20.04-x64/libClangSharp.runtime.ubuntu.20.04-x64.nuspec
index ba4c93d9..855ff158 100644
--- a/packages/libClangSharp/libClangSharp.runtime.ubuntu.20.04-x64/libClangSharp.runtime.ubuntu.20.04-x64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.ubuntu.20.04-x64/libClangSharp.runtime.ubuntu.20.04-x64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.ubuntu.20.04-x64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
ubuntu 20.04 x64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.win-x64/libClangSharp.runtime.win-x64.nuspec b/packages/libClangSharp/libClangSharp.runtime.win-x64/libClangSharp.runtime.win-x64.nuspec
index 7d97feba..f60cf287 100644
--- a/packages/libClangSharp/libClangSharp.runtime.win-x64/libClangSharp.runtime.win-x64.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.win-x64/libClangSharp.runtime.win-x64.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.win-x64
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
win x64 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp.runtime.win-x86/libClangSharp.runtime.win-x86.nuspec b/packages/libClangSharp/libClangSharp.runtime.win-x86/libClangSharp.runtime.win-x86.nuspec
index d3f73a4a..e05ba498 100644
--- a/packages/libClangSharp/libClangSharp.runtime.win-x86/libClangSharp.runtime.win-x86.nuspec
+++ b/packages/libClangSharp/libClangSharp.runtime.win-x86/libClangSharp.runtime.win-x86.nuspec
@@ -2,7 +2,7 @@
libClangSharp.runtime.win-x86
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
win x86 native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp/libClangSharp.nuspec b/packages/libClangSharp/libClangSharp/libClangSharp.nuspec
index b5efe85d..36e5a43b 100644
--- a/packages/libClangSharp/libClangSharp/libClangSharp.nuspec
+++ b/packages/libClangSharp/libClangSharp/libClangSharp.nuspec
@@ -2,7 +2,7 @@
libClangSharp
- 11.0.0-beta2
+ 11.0.0-beta3
Microsoft and Contributors
Microsoft and Contributors
true
@@ -10,7 +10,7 @@
https://github.com/microsoft/clangsharp
Multi-platform native library for libClangSharp.
Copyright © Microsoft and Contributors
-
+
diff --git a/packages/libClangSharp/libClangSharp/runtime.json b/packages/libClangSharp/libClangSharp/runtime.json
index dcf52d34..46dbdfdf 100644
--- a/packages/libClangSharp/libClangSharp/runtime.json
+++ b/packages/libClangSharp/libClangSharp/runtime.json
@@ -2,47 +2,47 @@
"runtimes": {
"freebsd.11-x64": {
"libClangSharp": {
- "libClangSharp.runtime.freebsd.11-x64": "11.0.0-beta2"
+ "libClangSharp.runtime.freebsd.11-x64": "11.0.0-beta3"
}
},
"freebsd.11-x86": {
"libClangSharp": {
- "libClangSharp.runtime.freebsd.11-x86": "11.0.0-beta2"
+ "libClangSharp.runtime.freebsd.11-x86": "11.0.0-beta3"
}
},
"linux-arm": {
"libClangSharp": {
- "libClangSharp.runtime.linux-arm": "11.0.0-beta2"
+ "libClangSharp.runtime.linux-arm": "11.0.0-beta3"
}
},
"linux-arm64": {
"libClangSharp": {
- "libClangSharp.runtime.linux-arm64": "11.0.0-beta2"
+ "libClangSharp.runtime.linux-arm64": "11.0.0-beta3"
}
},
"osx-x64": {
"libClangSharp": {
- "libClangSharp.runtime.osx-x64": "11.0.0-beta2"
+ "libClangSharp.runtime.osx-x64": "11.0.0-beta3"
}
},
"ubuntu.18.04-x64": {
"libClangSharp": {
- "libClangSharp.runtime.ubuntu.18.04-x64": "11.0.0-beta2"
+ "libClangSharp.runtime.ubuntu.18.04-x64": "11.0.0-beta3"
}
},
"ubuntu.20.04-x64": {
"libClangSharp": {
- "libClangSharp.runtime.ubuntu.20.04-x64": "11.0.0-beta2"
+ "libClangSharp.runtime.ubuntu.20.04-x64": "11.0.0-beta3"
}
},
"win-x64": {
"libClangSharp": {
- "libClangSharp.runtime.win-x64": "11.0.0-beta2"
+ "libClangSharp.runtime.win-x64": "11.0.0-beta3"
}
},
"win-x86": {
"libClangSharp": {
- "libClangSharp.runtime.win-x86": "11.0.0-beta2"
+ "libClangSharp.runtime.win-x86": "11.0.0-beta3"
}
}
}
diff --git a/scripts/azure-pipelines.yml b/scripts/azure-pipelines.yml
index 5612e963..bbdefb91 100644
--- a/scripts/azure-pipelines.yml
+++ b/scripts/azure-pipelines.yml
@@ -1,8 +1,8 @@
trigger:
-- master
+- main
pr:
-- master
+- main
jobs:
- template: azure-windows.yml
diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs
index 34112b45..8739a3dc 100644
--- a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs
+++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs
@@ -14,6 +14,7 @@ internal struct FunctionOrDelegateDesc
public string LibraryPath { get; set; }
public CallingConvention CallingConvention { get; set; }
public FunctionOrDelegateFlags Flags { get; set; }
+ public long? VtblIndex { get; set; }
public bool IsVirtual
{
diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs
index e9b6bc82..f2427bc4 100644
--- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs
+++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs
@@ -211,6 +211,13 @@ public void BeginFunctionOrDelegate(
WriteIndentedLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
}
+ var vtblIndex = desc.VtblIndex ?? -1;
+
+ if (vtblIndex != -1)
+ {
+ AddVtblIndexAttribute(vtblIndex);
+ }
+
if (desc.NativeTypeName is not null)
{
AddNativeTypeNameAttribute(desc.NativeTypeName, attributePrefix: "return: ");
diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs
index 5ace7376..6c48b44f 100644
--- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs
+++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs
@@ -256,7 +256,6 @@ private void AddNativeInheritanceAttribute(string inheritedFromName, string pref
Write("NativeInheritance");
Write('(');
-
Write('"');
Write(PInvokeGenerator.EscapeString(inheritedFromName));
Write('"');
@@ -273,6 +272,41 @@ private void AddNativeInheritanceAttribute(string inheritedFromName, string pref
}
}
+ private void AddVtblIndexAttribute(long vtblIndex, string prefix = null, string postfix = null, string attributePrefix = null)
+ {
+ if (prefix is null)
+ {
+ WriteIndentation();
+ }
+ else
+ {
+ WriteNewlineIfNeeded();
+ Write(prefix);
+ }
+
+ Write('[');
+
+ if (attributePrefix != null)
+ {
+ Write(attributePrefix);
+ }
+
+ Write("VtblIndex");
+ Write('(');
+ Write(vtblIndex);
+ Write(')');
+ Write(']');
+
+ if (postfix is null)
+ {
+ NeedsNewline = true;
+ }
+ else
+ {
+ Write(postfix);
+ }
+ }
+
private void AddNativeTypeNameAttribute(string nativeTypeName, string prefix = null, string postfix = null, string attributePrefix = null)
{
if (string.IsNullOrWhiteSpace(nativeTypeName))
diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
index d7d10bc1..99986beb 100644
--- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
+++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
@@ -653,7 +653,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
var body = functionDecl.Body;
var isVirtual = (cxxMethodDecl != null) && cxxMethodDecl.IsVirtual;
- var escapedName = isVirtual ? PrefixAndStripName(name) : EscapeAndStripName(name);
+ var escapedName = isVirtual ? PrefixAndStripName(name, cxxMethodDecl.OverloadIndex) : EscapeAndStripName(name);
if (!(functionDecl.DeclContext is CXXRecordDecl cxxRecordDecl))
{
@@ -704,7 +704,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
LibraryPath = isDllImport ? GetLibraryPath(name).Unquote() : null,
IsVirtual = isVirtual,
IsDllImport = isDllImport,
- HasFnPtrCodeGen = _config.GeneratePreviewCodeFnptr,
+ HasFnPtrCodeGen = !_config.ExcludeFnptrCodegen,
SetLastError = GetSetLastError(name),
IsCxx = cxxMethodDecl is not null,
IsStatic = isDllImport || (cxxMethodDecl?.IsStatic ?? true),
@@ -1165,7 +1165,9 @@ private void VisitRecordDecl(RecordDecl recordDecl)
Offset = null,
NeedsNewKeyword = false
};
+
_outputBuilder.BeginField(in fieldDesc);
+
if (_config.GenerateExplicitVtbls)
{
_outputBuilder.WriteRegularField("Vtbl*", "lpVtbl");
@@ -1188,8 +1190,7 @@ private void VisitRecordDecl(RecordDecl recordDecl)
{
var parent = GetRemappedCursorName(baseCxxRecordDecl);
var baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base");
- baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier,
- tryRemapOperatorName: true);
+ baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true);
var fieldDesc = new FieldDesc
{
@@ -1208,8 +1209,7 @@ private void VisitRecordDecl(RecordDecl recordDecl)
}
}
- if ((_testOutputBuilder != null) && !recordDecl.IsAnonymousStructOrUnion &&
- !(recordDecl.DeclContext is RecordDecl))
+ if ((_testOutputBuilder != null) && !recordDecl.IsAnonymousStructOrUnion && !(recordDecl.DeclContext is RecordDecl))
{
_testOutputBuilder.WriteIndented("/// Validates that the ());
+ OutputDelegateSignatures(cxxRecordDecl, cxxRecordDecl);
}
}
@@ -1363,17 +1361,17 @@ private void VisitRecordDecl(RecordDecl recordDecl)
_outputBuilder.EmitCompatibleCodeSupport();
}
- if (!_config.GeneratePreviewCodeFnptr)
+ if (_config.ExcludeFnptrCodegen)
{
_outputBuilder.EmitFnPtrSupport();
}
- OutputVtblHelperMethods(cxxRecordDecl, cxxRecordDecl, hitsPerName: new Dictionary());
+ OutputVtblHelperMethods(cxxRecordDecl, cxxRecordDecl);
if (_config.GenerateExplicitVtbls)
{
_outputBuilder.BeginExplicitVtbl();
- OutputVtblEntries(cxxRecordDecl, cxxRecordDecl, hitsPerName: new Dictionary());
+ OutputVtblEntries(cxxRecordDecl, cxxRecordDecl);
_outputBuilder.EndExplicitVtbl();
}
}
@@ -1388,24 +1386,15 @@ private void VisitRecordDecl(RecordDecl recordDecl)
}
StopUsingOutputBuilder();
- string FixupNameForMultipleHits(CXXMethodDecl cxxMethodDecl, Dictionary hitsPerName)
+ string FixupNameForMultipleHits(CXXMethodDecl cxxMethodDecl)
{
var remappedName = GetRemappedCursorName(cxxMethodDecl);
+ var overloadIndex = cxxMethodDecl.OverloadIndex;
- if (hitsPerName.TryGetValue(remappedName, out int hits))
- {
- hitsPerName[remappedName] = (hits + 1);
-
- var name = GetCursorName(cxxMethodDecl);
- var remappedNames = (Dictionary)_config.RemappedNames;
-
- remappedNames[name] = $"{remappedName}{hits}";
- }
- else
+ if (overloadIndex != 0)
{
- hitsPerName.Add(remappedName, 1);
+ remappedName = $"{remappedName}{overloadIndex}";
}
-
return remappedName;
}
@@ -1441,13 +1430,12 @@ bool HasFields(RecordDecl recordDecl)
return false;
}
- void OutputDelegateSignatures(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl,
- Dictionary hitsPerName)
+ void OutputDelegateSignatures(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl)
{
foreach (var cxxBaseSpecifier in cxxRecordDecl.Bases)
{
var baseCxxRecordDecl = GetRecordDeclForBaseSpecifier(cxxBaseSpecifier);
- OutputDelegateSignatures(rootCxxRecordDecl, baseCxxRecordDecl, hitsPerName);
+ OutputDelegateSignatures(rootCxxRecordDecl, baseCxxRecordDecl);
}
foreach (var cxxMethodDecl in cxxRecordDecl.Methods)
@@ -1457,14 +1445,13 @@ void OutputDelegateSignatures(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxx
continue;
}
- if (!_config.GeneratePreviewCodeFnptr)
+ if (_config.ExcludeFnptrCodegen)
{
_outputBuilder.WriteDivider();
- var remappedName = FixupNameForMultipleHits(cxxMethodDecl, hitsPerName);
+ var remappedName = FixupNameForMultipleHits(cxxMethodDecl);
Debug.Assert(CurrentContext == rootCxxRecordDecl);
Visit(cxxMethodDecl);
- RestoreNameForMultipleHits(cxxMethodDecl, hitsPerName, remappedName);
}
}
}
@@ -1491,29 +1478,26 @@ void OutputMethods(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl)
}
}
- void OutputVtblEntries(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl,
- Dictionary hitsPerName)
+ void OutputVtblEntries(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl)
{
foreach (var cxxBaseSpecifier in cxxRecordDecl.Bases)
{
var baseCxxRecordDecl = GetRecordDeclForBaseSpecifier(cxxBaseSpecifier);
- OutputVtblEntries(rootCxxRecordDecl, baseCxxRecordDecl, hitsPerName);
+ OutputVtblEntries(rootCxxRecordDecl, baseCxxRecordDecl);
}
var cxxMethodDecls = cxxRecordDecl.Methods;
if (cxxMethodDecls.Count != 0)
{
- foreach (var cxxMethodDecl in cxxMethodDecls)
+ foreach (var cxxMethodDecl in cxxMethodDecls.OrderBy((cxxmd) => cxxmd.VtblIndex))
{
- OutputVtblEntry(rootCxxRecordDecl, cxxMethodDecl, hitsPerName);
- _outputBuilder.WriteDivider();
+ OutputVtblEntry(rootCxxRecordDecl, cxxMethodDecl);
}
}
}
- void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl,
- Dictionary hitsPerName)
+ void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl)
{
if (!cxxMethodDecl.IsVirtual || IsExcluded(cxxMethodDecl))
{
@@ -1524,10 +1508,8 @@ void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl,
out var nativeTypeName);
var accessSpecifier = GetAccessSpecifier(cxxMethodDecl);
- var remappedName = FixupNameForMultipleHits(cxxMethodDecl, hitsPerName);
- var name = GetRemappedCursorName(cxxMethodDecl);
- var escapedName = EscapeAndStripName(name);
- RestoreNameForMultipleHits(cxxMethodDecl, hitsPerName, remappedName);
+ var remappedName = FixupNameForMultipleHits(cxxMethodDecl);
+ var escapedName = EscapeAndStripName(remappedName);
var desc = new FieldDesc
{
@@ -1541,9 +1523,11 @@ void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl,
_outputBuilder.BeginField(in desc);
_outputBuilder.WriteRegularField(cxxMethodDeclTypeName, escapedName);
_outputBuilder.EndField();
+
+ _outputBuilder.WriteDivider();
}
- void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl, Dictionary hitsPerName)
+ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl)
{
if (!cxxMethodDecl.IsVirtual)
{
@@ -1558,27 +1542,26 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
var currentContext = _context.AddLast(cxxMethodDecl);
var accessSpecifier = GetAccessSpecifier(cxxMethodDecl);
var returnType = cxxMethodDecl.ReturnType;
- var returnTypeName =
- GetRemappedTypeName(cxxMethodDecl, cxxRecordDecl, returnType, out var nativeTypeName);
+ var returnTypeName = GetRemappedTypeName(cxxMethodDecl, cxxRecordDecl, returnType, out var nativeTypeName);
- var remappedName = FixupNameForMultipleHits(cxxMethodDecl, hitsPerName);
+ var remappedName = FixupNameForMultipleHits(cxxMethodDecl);
var name = GetRemappedCursorName(cxxMethodDecl);
- RestoreNameForMultipleHits(cxxMethodDecl, hitsPerName, remappedName);
var desc = new FunctionOrDelegateDesc<(string Name, PInvokeGenerator This)>
{
AccessSpecifier = accessSpecifier,
CustomAttrGeneratorData = (name, this),
IsAggressivelyInlined = _config.GenerateAggressiveInlining,
- EscapedName = EscapeAndStripName(remappedName),
+ EscapedName = EscapeAndStripName(name),
WriteCustomAttrs = static _ => {},
IsMemberFunction = true,
NativeTypeName = nativeTypeName,
- NeedsNewKeyword = NeedsNewKeyword(remappedName, cxxMethodDecl.Parameters),
- HasFnPtrCodeGen = _config.GeneratePreviewCodeFnptr,
+ NeedsNewKeyword = NeedsNewKeyword(name, cxxMethodDecl.Parameters),
+ HasFnPtrCodeGen = !_config.ExcludeFnptrCodegen,
IsCtxCxxRecord = true,
IsCxxRecordCtxUnsafe = IsUnsafe(cxxRecordDecl),
- IsUnsafe = true
+ IsUnsafe = true,
+ VtblIndex = _config.GenerateVtblIndexAttribute ? cxxMethodDecl.VtblIndex : -1,
};
_outputBuilder.BeginFunctionOrDelegate(in desc, ref _isMethodClassUnsafe);
@@ -1629,11 +1612,11 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
body.Write('*');
}
- if (!_config.GeneratePreviewCodeFnptr)
+ if (_config.ExcludeFnptrCodegen)
{
body.Write("Marshal.GetDelegateForFunctionPointer<");
body.BeginMarker("delegate");
- body.Write(PrefixAndStripName(name));
+ body.Write(PrefixAndStripName(name, cxxMethodDecl.OverloadIndex));
body.EndMarker("delegate");
body.Write(">(");
}
@@ -1642,7 +1625,7 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
{
body.Write("lpVtbl->");
body.BeginMarker("vtbl", new KeyValuePair("explicit", true));
- body.Write(EscapeAndStripName(name));
+ body.Write(EscapeAndStripName(remappedName));
body.EndMarker("vtbl");
}
else
@@ -1650,7 +1633,7 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
var cxxMethodDeclTypeName =
GetRemappedTypeName(cxxMethodDecl, cxxRecordDecl, cxxMethodDecl.Type, out var _);
- if (_config.GeneratePreviewCodeFnptr)
+ if (!_config.ExcludeFnptrCodegen)
{
body.Write('(');
}
@@ -1663,13 +1646,13 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
body.EndMarker("vtbl");
body.Write("])");
- if (_config.GeneratePreviewCodeFnptr)
+ if (!_config.ExcludeFnptrCodegen)
{
body.Write(')');
}
}
- if (!_config.GeneratePreviewCodeFnptr)
+ if (_config.ExcludeFnptrCodegen)
{
body.Write(')');
}
@@ -1738,12 +1721,12 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
_context.RemoveLast();
}
- void OutputVtblHelperMethods(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl, Dictionary hitsPerName)
+ void OutputVtblHelperMethods(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxRecordDecl)
{
foreach (var cxxBaseSpecifier in cxxRecordDecl.Bases)
{
var baseCxxRecordDecl = GetRecordDeclForBaseSpecifier(cxxBaseSpecifier);
- OutputVtblHelperMethods(rootCxxRecordDecl, baseCxxRecordDecl, hitsPerName);
+ OutputVtblHelperMethods(rootCxxRecordDecl, baseCxxRecordDecl);
}
var cxxMethodDecls = cxxRecordDecl.Methods;
@@ -1752,31 +1735,11 @@ void OutputVtblHelperMethods(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxR
foreach (var cxxMethodDecl in cxxMethodDecls)
{
_outputBuilder.WriteDivider();
- OutputVtblHelperMethod(rootCxxRecordDecl, cxxMethodDecl, hitsPerName);
- }
- }
-
- void RestoreNameForMultipleHits(CXXMethodDecl cxxMethodDecl, Dictionary hitsPerName,
- string remappedName)
- {
- if (hitsPerName[remappedName] != 1)
- {
- var name = GetCursorName(cxxMethodDecl);
- var remappedNames = (Dictionary)_config.RemappedNames;
-
- if (name.Equals(remappedName))
- {
- remappedNames.Remove(name);
- }
- else
- {
- remappedNames[name] = remappedName;
- }
+ OutputVtblHelperMethod(rootCxxRecordDecl, cxxMethodDecl);
}
}
- void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl, string contextName,
- ref int index, ref long previousSize, ref long remainingBits)
+ void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl, string contextName, ref int index, ref long previousSize, ref long remainingBits)
{
Debug.Assert(fieldDecl.IsBitField);
@@ -2226,6 +2189,8 @@ void VisitConstantArrayFieldDecl(RecordDecl recordDecl, FieldDecl constantArray)
elementType = subConstantArrayType.ElementType;
}
+ var firstFieldName = "";
+
for (long i = 0; i < totalSize; i++)
{
var dimension = sizePerDimension[0];
@@ -2253,6 +2218,11 @@ void VisitConstantArrayFieldDecl(RecordDecl recordDecl, FieldDecl constantArray)
sizePerDimension[d] = dimension;
}
+ if (firstFieldName == "")
+ {
+ firstFieldName = fieldName;
+ }
+
var fieldDesc = new FieldDesc
{
AccessSpecifier = accessSpecifier,
@@ -2295,7 +2265,9 @@ void VisitConstantArrayFieldDecl(RecordDecl recordDecl, FieldDecl constantArray)
code.WriteIndented("fixed (");
code.Write(typeName);
- code.WriteLine("* pThis = &e0)");
+ code.Write("* pThis = &");
+ code.Write(firstFieldName);
+ code.WriteLine(')');
code.WriteBlockStart();
code.WriteIndented("return ref pThis[index]");
code.WriteSemicolon();
@@ -2378,7 +2350,9 @@ void VisitConstantArrayFieldDecl(RecordDecl recordDecl, FieldDecl constantArray)
_outputBuilder.BeginBody(true);
code = _outputBuilder.BeginCSharpCode();
- code.Write("MemoryMarshal.CreateSpan(ref e0, ");
+ code.Write("MemoryMarshal.CreateSpan(ref ");
+ code.Write(firstFieldName);
+ code.Write(", ");
if (type.Size == 1)
{
@@ -2412,7 +2386,7 @@ private void VisitTypedefDecl(TypedefDecl typedefDecl)
void ForFunctionProtoType(TypedefDecl typedefDecl, FunctionProtoType functionProtoType, Type parentType)
{
- if (_config.GeneratePreviewCodeFnptr)
+ if (!_config.ExcludeFnptrCodegen)
{
return;
}
@@ -2581,8 +2555,7 @@ private void VisitVarDecl(VarDecl varDecl)
{
ForDeclStmt(varDecl, declStmt);
}
- else if (IsPrevContextDecl(out _) || IsPrevContextDecl(out _) ||
- IsPrevContextDecl(out _))
+ else if (IsPrevContextDecl(out _) || IsPrevContextDecl(out _) || IsPrevContextDecl(out _))
{
if (!varDecl.HasInit)
{
@@ -2623,9 +2596,7 @@ private void VisitVarDecl(VarDecl varDecl)
StartUsingOutputBuilder(_config.MethodClassName);
openedOutputBuilder = true;
- if (IsUnsafe(varDecl, type) && (!varDecl.HasInit ||
- !IsStmtAsWritten(varDecl.Init, out _,
- removeParens: true)))
+ if (IsUnsafe(varDecl, type) && (!varDecl.HasInit || !IsStmtAsWritten(varDecl.Init, out _, removeParens: true)))
{
_isMethodClassUnsafe = true;
}
@@ -2720,9 +2691,14 @@ private void VisitVarDecl(VarDecl varDecl)
}
}
- if (!isStringLiteral && type is ArrayType)
+ if (!isStringLiteral && type is ArrayType arrayType)
{
- typeName += "[]";
+ do
+ {
+ typeName += "[]";
+ arrayType = arrayType.ElementType as ArrayType;
+ }
+ while (arrayType is not null);
}
var desc = new ConstantDesc
diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
index f7f788b9..12d4306c 100644
--- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
+++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
@@ -765,25 +765,42 @@ void ForArrayType(InitListExpr initListExpr, ArrayType arrayType)
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out var nativeTypeName);
outputBuilder.Write(typeName);
- outputBuilder.Write('[');
- long size = -1;
+ long rootSize = -1;
- if (arrayType is ConstantArrayType constantArrayType)
+ do
{
- size = constantArrayType.Size;
- }
- else
- {
- AddDiagnostic(DiagnosticLevel.Error, $"Unsupported array type kind: '{type.KindSpelling}'. Generated bindings may be incomplete.", initListExpr);
- }
+ outputBuilder.Write('[');
+ long size = -1;
- if (size != -1)
- {
- outputBuilder.Write(size);
+ if (arrayType is ConstantArrayType constantArrayType)
+ {
+ size = constantArrayType.Size;
+ }
+ else
+ {
+ AddDiagnostic(DiagnosticLevel.Error, $"Unsupported array type kind: '{type.KindSpelling}'. Generated bindings may be incomplete.", initListExpr);
+ }
+
+ if (rootSize == -1)
+ {
+ if (size != -1)
+ {
+ rootSize = size;
+ outputBuilder.Write(size);
+ }
+ else
+ {
+ rootSize = 0;
+ }
+ }
+
+ outputBuilder.Write(']');
+ arrayType = arrayType.ElementType as ArrayType;
}
+ while (arrayType is not null);
- outputBuilder.WriteLine(']');
+ outputBuilder.WriteNewline();
outputBuilder.WriteBlockStart();
for (int i = 0; i < initListExpr.Inits.Count; i++)
@@ -793,7 +810,7 @@ void ForArrayType(InitListExpr initListExpr, ArrayType arrayType)
outputBuilder.WriteLine(',');
}
- for (int i = initListExpr.Inits.Count; i < size; i++)
+ for (int i = initListExpr.Inits.Count; i < rootSize; i++)
{
outputBuilder.WriteIndentedLine("default,");
}
diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
index 994e1d88..ee5b76e2 100644
--- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
+++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
@@ -1306,7 +1306,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string
{
if (_config.GenerateUnixTypes)
{
- name = _config.GeneratePreviewCodeNint ? "nuint" : "UIntPtr";
+ name = _config.ExcludeNIntCodegen ? "UIntPtr" : "nuint";
}
else
{
@@ -1356,7 +1356,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string
{
if (_config.GenerateUnixTypes)
{
- name = _config.GeneratePreviewCodeNint ? "nint" : "IntPtr";
+ name = _config.ExcludeNIntCodegen ? "IntPtr" : "nint";
}
else
{
@@ -1437,7 +1437,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string
typeName = "byte";
}
- if (typeName.EndsWith("*"))
+ if (typeName.EndsWith("*") || typeName.Contains("delegate*"))
{
// Pointers are not yet supported as generic arguments; remap to IntPtr
typeName = "IntPtr";
@@ -1517,7 +1517,7 @@ private string GetTypeNameForPointeeType(Cursor cursor, Cursor context, Type poi
}
else if (pointeeType is FunctionType functionType)
{
- if (_config.GeneratePreviewCodeFnptr && (functionType is FunctionProtoType functionProtoType))
+ if (!_config.ExcludeFnptrCodegen && (functionType is FunctionProtoType functionProtoType))
{
var remappedName = GetRemappedName(name, cursor, tryRemapOperatorName: false);
var callConv = GetCallingConvention(cursor, functionType.CallConv, remappedName);
@@ -3241,14 +3241,14 @@ private void ParenthesizeStmt(Stmt stmt)
}
}
- private string PrefixAndStripName(string name)
+ private string PrefixAndStripName(string name, uint overloadIndex)
{
if (name.StartsWith(_config.MethodPrefixToStrip))
{
name = name.Substring(_config.MethodPrefixToStrip.Length);
}
- return '_' + name;
+ return $"_{name}{((overloadIndex != 0) ? overloadIndex.ToString() : "")}";
}
private void StartUsingOutputBuilder(string name, bool includeTestOutput = false)
diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs
index 5b00a6e9..5b08f440 100644
--- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs
+++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs
@@ -105,7 +105,7 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
if (!_options.HasFlag(PInvokeGeneratorConfigurationOptions.NoDefaultRemappings))
{
- if (GeneratePreviewCodeNint)
+ if (!ExcludeNIntCodegen)
{
_remappedNames.Add("intptr_t", "nint");
_remappedNames.Add("ptrdiff_t", "nint");
@@ -147,9 +147,9 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
public bool GenerateMacroBindings => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMacroBindings);
- public bool GeneratePreviewCodeFnptr => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeFnptr);
+ public bool ExcludeFnptrCodegen => GenerateCompatibleCode || _options.HasFlag(PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen);
- public bool GeneratePreviewCodeNint => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeNint);
+ public bool ExcludeNIntCodegen => GenerateCompatibleCode || _options.HasFlag(PInvokeGeneratorConfigurationOptions.ExcludeNIntCodegen);
public bool GenerateMultipleFiles => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles);
@@ -177,6 +177,8 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
public bool GenerateNativeInheritanceAttribute => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ public bool GenerateVtblIndexAttribute => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+
public string MethodClassName { get; }
public string MethodPrefixToStrip { get;}
diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs
index bf09c624..cd005432 100644
--- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs
+++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs
@@ -17,11 +17,9 @@ public enum PInvokeGeneratorConfigurationOptions
GenerateCompatibleCode = 0x00000008,
- GeneratePreviewCodeNint = 0x00000010,
+ ExcludeNIntCodegen = 0x00000010,
- GeneratePreviewCodeFnptr = 0x00000020,
-
- GeneratePreviewCode = GeneratePreviewCodeNint | GeneratePreviewCodeFnptr,
+ ExcludeFnptrCodegen = 0x00000020,
LogExclusions = 0x00000040,
@@ -54,5 +52,9 @@ public enum PInvokeGeneratorConfigurationOptions
GenerateNativeInheritanceAttribute = 0x00100000,
DontUseUsingStaticsForEnums = 0x00200000,
+
+ GenerateVtblIndexAttribute = 0x00400000,
+
+ GeneratePreviewCode = 0x00800000,
}
}
diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs
index 0b0d31db..8cc2ca9a 100644
--- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs
+++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs
@@ -122,6 +122,13 @@ public void BeginFunctionOrDelegate(
_sb.Append(" unsafe=\"true\"");
}
+ var vtblIndex = desc.VtblIndex ?? -1;
+
+ if (vtblIndex != -1)
+ {
+ _sb.Append($" vtblindex=\"{vtblIndex}\"");
+ }
+
_sb.Append('>');
desc.WriteCustomAttrs(desc.CustomAttrGeneratorData);
diff --git a/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs
index ab9fc613..082dbe98 100644
--- a/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs
+++ b/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs
@@ -2,12 +2,14 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using ClangSharp.Interop;
namespace ClangSharp
{
public class CXXMethodDecl : FunctionDecl
{
+ private readonly Lazy _overloadIndex;
private readonly Lazy> _overriddenMethods;
private readonly Lazy _thisType;
private readonly Lazy _thisObjectType;
@@ -23,6 +25,25 @@ private protected CXXMethodDecl(CXCursor handle, CXCursorKind expectedCursorKind
throw new ArgumentException(nameof(handle));
}
+ _overloadIndex = new Lazy(() => {
+ var index = 0u;
+ var name = Name;
+
+ foreach (var methodDecl in Parent.Methods)
+ {
+ if (methodDecl == this)
+ {
+ break;
+ }
+ else if (methodDecl.Name == name)
+ {
+ index++;
+ }
+ }
+
+ return index;
+ });
+
_overriddenMethods = new Lazy>(() => {
var numOverriddenMethods = Handle.NumMethods;
var overriddenMethods = new List(numOverriddenMethods);
@@ -50,6 +71,8 @@ private protected CXXMethodDecl(CXCursor handle, CXCursorKind expectedCursorKind
public new CXXMethodDecl MostRecentDecl => (CXXMethodDecl)base.MostRecentDecl;
+ public uint OverloadIndex => _overloadIndex.Value;
+
public IReadOnlyList OverriddenMethods => _overriddenMethods.Value;
public new CXXRecordDecl Parent => (CXXRecordDecl)base.Parent;
@@ -60,6 +83,6 @@ private protected CXXMethodDecl(CXCursor handle, CXCursorKind expectedCursorKind
public Type ThisObjectType => _thisObjectType.Value;
- public long VtblIndex => Handle.VtblIdx;
+ public long VtblIndex => IsVirtual ? Handle.VtblIdx : -1;
}
}
diff --git a/sources/ClangSharp/Interop.Extensions/CX_TemplateName.cs b/sources/ClangSharp/Interop.Extensions/CX_TemplateName.cs
index 9575cf9a..82f97622 100644
--- a/sources/ClangSharp/Interop.Extensions/CX_TemplateName.cs
+++ b/sources/ClangSharp/Interop.Extensions/CX_TemplateName.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_AtomicOperatorKind.cs b/sources/ClangSharp/Interop/CX_AtomicOperatorKind.cs
index cdefc3a0..f65f3876 100644
--- a/sources/ClangSharp/Interop/CX_AtomicOperatorKind.cs
+++ b/sources/ClangSharp/Interop/CX_AtomicOperatorKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_AttrKind.cs b/sources/ClangSharp/Interop/CX_AttrKind.cs
index db56c685..03daf59f 100644
--- a/sources/ClangSharp/Interop/CX_AttrKind.cs
+++ b/sources/ClangSharp/Interop/CX_AttrKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_BinaryOperatorKind.cs b/sources/ClangSharp/Interop/CX_BinaryOperatorKind.cs
index f4eaa8b0..9d5ed741 100644
--- a/sources/ClangSharp/Interop/CX_BinaryOperatorKind.cs
+++ b/sources/ClangSharp/Interop/CX_BinaryOperatorKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_CapturedRegionKind.cs b/sources/ClangSharp/Interop/CX_CapturedRegionKind.cs
index d302ec73..7680217d 100644
--- a/sources/ClangSharp/Interop/CX_CapturedRegionKind.cs
+++ b/sources/ClangSharp/Interop/CX_CapturedRegionKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_CastKind.cs b/sources/ClangSharp/Interop/CX_CastKind.cs
index 38be2a32..8ed3ab2a 100644
--- a/sources/ClangSharp/Interop/CX_CastKind.cs
+++ b/sources/ClangSharp/Interop/CX_CastKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_CharacterKind.cs b/sources/ClangSharp/Interop/CX_CharacterKind.cs
index 2e4bbbf4..ce19a042 100644
--- a/sources/ClangSharp/Interop/CX_CharacterKind.cs
+++ b/sources/ClangSharp/Interop/CX_CharacterKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_ConstructionKind.cs b/sources/ClangSharp/Interop/CX_ConstructionKind.cs
index 7dfd88c9..7744f9e9 100644
--- a/sources/ClangSharp/Interop/CX_ConstructionKind.cs
+++ b/sources/ClangSharp/Interop/CX_ConstructionKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_DeclKind.cs b/sources/ClangSharp/Interop/CX_DeclKind.cs
index 116e98b2..d4e01e03 100644
--- a/sources/ClangSharp/Interop/CX_DeclKind.cs
+++ b/sources/ClangSharp/Interop/CX_DeclKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_ExprDependence.cs b/sources/ClangSharp/Interop/CX_ExprDependence.cs
index 2bf240fc..e6659fae 100644
--- a/sources/ClangSharp/Interop/CX_ExprDependence.cs
+++ b/sources/ClangSharp/Interop/CX_ExprDependence.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
using System;
diff --git a/sources/ClangSharp/Interop/CX_FloatingSemantics.cs b/sources/ClangSharp/Interop/CX_FloatingSemantics.cs
index a6580384..b3ccc1c1 100644
--- a/sources/ClangSharp/Interop/CX_FloatingSemantics.cs
+++ b/sources/ClangSharp/Interop/CX_FloatingSemantics.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_OverloadedOperatorKind.cs b/sources/ClangSharp/Interop/CX_OverloadedOperatorKind.cs
index c663baba..de18d2b5 100644
--- a/sources/ClangSharp/Interop/CX_OverloadedOperatorKind.cs
+++ b/sources/ClangSharp/Interop/CX_OverloadedOperatorKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_StmtClass.cs b/sources/ClangSharp/Interop/CX_StmtClass.cs
index 40b64da4..431f6f7a 100644
--- a/sources/ClangSharp/Interop/CX_StmtClass.cs
+++ b/sources/ClangSharp/Interop/CX_StmtClass.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TemplateArgument.cs b/sources/ClangSharp/Interop/CX_TemplateArgument.cs
index b5ce2cbf..cd9c5ed3 100644
--- a/sources/ClangSharp/Interop/CX_TemplateArgument.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateArgument.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TemplateArgumentDependence.cs b/sources/ClangSharp/Interop/CX_TemplateArgumentDependence.cs
index b22953bd..99843e62 100644
--- a/sources/ClangSharp/Interop/CX_TemplateArgumentDependence.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateArgumentDependence.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
using System;
diff --git a/sources/ClangSharp/Interop/CX_TemplateArgumentLoc.cs b/sources/ClangSharp/Interop/CX_TemplateArgumentLoc.cs
index 3ded9172..e892122e 100644
--- a/sources/ClangSharp/Interop/CX_TemplateArgumentLoc.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateArgumentLoc.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TemplateName.cs b/sources/ClangSharp/Interop/CX_TemplateName.cs
index fe376011..68c14138 100644
--- a/sources/ClangSharp/Interop/CX_TemplateName.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateName.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TemplateNameKind.cs b/sources/ClangSharp/Interop/CX_TemplateNameKind.cs
index b96b036a..8cd46f5f 100644
--- a/sources/ClangSharp/Interop/CX_TemplateNameKind.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateNameKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TemplateSpecializationKind.cs b/sources/ClangSharp/Interop/CX_TemplateSpecializationKind.cs
index b118d1fe..781212ed 100644
--- a/sources/ClangSharp/Interop/CX_TemplateSpecializationKind.cs
+++ b/sources/ClangSharp/Interop/CX_TemplateSpecializationKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_TypeClass.cs b/sources/ClangSharp/Interop/CX_TypeClass.cs
index 92a483a8..a2f602d4 100644
--- a/sources/ClangSharp/Interop/CX_TypeClass.cs
+++ b/sources/ClangSharp/Interop/CX_TypeClass.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_UnaryExprOrTypeTrait.cs b/sources/ClangSharp/Interop/CX_UnaryExprOrTypeTrait.cs
index 9f52bbec..3b7e75d8 100644
--- a/sources/ClangSharp/Interop/CX_UnaryExprOrTypeTrait.cs
+++ b/sources/ClangSharp/Interop/CX_UnaryExprOrTypeTrait.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_UnaryOperatorKind.cs b/sources/ClangSharp/Interop/CX_UnaryOperatorKind.cs
index 42808fd1..e12640da 100644
--- a/sources/ClangSharp/Interop/CX_UnaryOperatorKind.cs
+++ b/sources/ClangSharp/Interop/CX_UnaryOperatorKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/CX_VariableCaptureKind.cs b/sources/ClangSharp/Interop/CX_VariableCaptureKind.cs
index 70ec65d2..add3f5a9 100644
--- a/sources/ClangSharp/Interop/CX_VariableCaptureKind.cs
+++ b/sources/ClangSharp/Interop/CX_VariableCaptureKind.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
namespace ClangSharp.Interop
{
diff --git a/sources/ClangSharp/Interop/clangsharp.cs b/sources/ClangSharp/Interop/clangsharp.cs
index e8a52c14..826b8a59 100644
--- a/sources/ClangSharp/Interop/clangsharp.cs
+++ b/sources/ClangSharp/Interop/clangsharp.cs
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
using System;
using System.Runtime.InteropServices;
diff --git a/sources/ClangSharp/Types/Type.cs b/sources/ClangSharp/Types/Type.cs
index 0fa23536..fa4b5955 100644
--- a/sources/ClangSharp/Types/Type.cs
+++ b/sources/ClangSharp/Types/Type.cs
@@ -61,7 +61,7 @@ public TagDecl AsTagDecl
public CXType Handle { get; }
- public bool IsAnyPointerType => IsAnyPointerType || IsObjCObjectPointerType;
+ public bool IsAnyPointerType => IsPointerType || IsObjCObjectPointerType;
public bool IsExtIntType => CanonicalType is ExtIntType;
diff --git a/sources/ClangSharpPInvokeGenerator/Program.cs b/sources/ClangSharpPInvokeGenerator/Program.cs
index a0a1832e..dc37edec 100644
--- a/sources/ClangSharpPInvokeGenerator/Program.cs
+++ b/sources/ClangSharpPInvokeGenerator/Program.cs
@@ -46,7 +46,9 @@ public class Program
("exclude-default-remappings", "Default remappings for well known types should not be added. This currently includes intptr_t, ptrdiff_t, size_t, and uintptr_t"),
("exclude-empty-records", "Bindings for records that contain no members should not be generated. These are commonly encountered for opaque handle like types such as HWND."),
("exclude-enum-operators", "Bindings for operators over enum types should not be generated. These are largely unnecessary in C# as the operators are available by default."),
+ ("exclude-fnptr-codegen", "Generated bindings for latest or preview codegen should not use function pointers."),
("exclude-funcs-with-body", "Bindings for functions with bodies should not be generated."),
+ ("preview-codegen-nint", "Generated bindings for latest or preview codegen should not use nint or nuint."),
("exclude-using-statics-for-enums", "Enum usages should be fully qualified and should not include a corresponding 'using static EnumName;'"),
("", ""), // VTBL Options
@@ -62,20 +64,16 @@ public class Program
("", ""), // Generation Options
("generate-aggressive-inlining", "[MethodImpl(MethodImplOptions.AggressiveInlining)] should be added to generated helper functions."),
- ("generate-cpp-attributes", "A [CppAttributeList(\"\")] should be generated to document the encountered C++ attributes."),
+ ("generate-cpp-attributes", "[CppAttributeList(\"\")] should be generated to document the encountered C++ attributes."),
("generate-macro-bindings", "Bindings for macro-definitions should be generated. This currently only works with value like macros and not function-like ones."),
- ("generate-native-inheritance-attribute", "A [NativeInheritance(\"\")] attribute should be generated to document the encountered C++ base type."),
+ ("generate-native-inheritance-attribute", "[NativeInheritance(\"\")] attribute should be generated to document the encountered C++ base type."),
+ ("generate-vtbl-index-attribute", "[VtblIndex(#)] attribute should be generated to document the underlying VTBL index for a helper method."),
("", ""), // Logging Options
("log-exclusions", "A list of excluded declaration types should be generated. This will also log if the exclusion was due to an exact or partial match."),
("log-potential-typedef-remappings", "A list of potential typedef remappings should be generated. This can help identify missing remappings."),
("log-visited-files", "A list of the visited files should be generated. This can help identify traversal issues."),
-
- ("", ""), // Preview Options
-
- ("preview-codegen-fnptr", "Generated bindings should use function pointers instead of IntPtr where possible."),
- ("preview-codegen-nint", "Generated bindings should use nint and nuint instead of IntPtr and UIntPtr where possible."),
};
public static async Task Main(params string[] args)
@@ -265,12 +263,24 @@ public static int Run(InvocationContext context)
break;
}
+ case "exclude-fnptr-codegen":
+ {
+ configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen;
+ break;
+ }
+
case "exclude-funcs-with-body":
{
configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeFunctionsWithBody;
break;
}
+ case "exclude-nint-codegen":
+ {
+ configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeNIntCodegen;
+ break;
+ }
+
case "exclude-using-statics-for-enums":
case "dont-use-using-statics-for-enums":
{
@@ -350,6 +360,12 @@ public static int Run(InvocationContext context)
break;
}
+ case "generate-vtbl-index-attribute":
+ {
+ configOptions |= PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute;
+ break;
+ }
+
// Logging Options
case "log-exclusions":
@@ -370,22 +386,6 @@ public static int Run(InvocationContext context)
break;
}
- // Preview Options
-
- case "preview-codegen-fnptr":
- {
- configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
- configOptions |= PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeFnptr;
- break;
- }
-
- case "preview-codegen-nint":
- {
- configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
- configOptions |= PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeNint;
- break;
- }
-
// Legacy Options
case "default-remappings":
diff --git a/sources/ClangSharpPInvokeGenerator/Properties/GenerateClangSharp-LICENSE.txt b/sources/ClangSharpPInvokeGenerator/Properties/GenerateClangSharp-LICENSE.txt
index 919fba06..0f5e7923 100644
--- a/sources/ClangSharpPInvokeGenerator/Properties/GenerateClangSharp-LICENSE.txt
+++ b/sources/ClangSharpPInvokeGenerator/Properties/GenerateClangSharp-LICENSE.txt
@@ -1,2 +1,2 @@
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
-// Ported from https://github.com/microsoft/ClangSharp/blob/master/sources/libClangSharp
+// Ported from https://github.com/microsoft/ClangSharp/blob/main/sources/libClangSharp
diff --git a/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json b/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json
index 5fdf6cc0..c69b228f 100644
--- a/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json
+++ b/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json
@@ -15,7 +15,7 @@
},
"GenerateLocal": {
"commandName": "Project",
- "commandLineArgs": "-?"
+ "commandLineArgs": "-c help"
}
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs
index 85ce0111..dc5791fd 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs
@@ -34,6 +34,9 @@ public abstract class CXXMethodDeclarationTest : PInvokeGeneratorTest
[Fact]
public abstract Task NewKeywordVirtualTest();
+ [Fact]
+ public abstract Task NewKeywordVirtualWithExplicitVtblTest();
+
[Fact]
public abstract Task OperatorTest();
@@ -51,5 +54,8 @@ public abstract class CXXMethodDeclarationTest : PInvokeGeneratorTest
[Fact]
public abstract Task VirtualTest();
+
+ [Fact]
+ public abstract Task VirtualWithVtblIndexAttributeTest();
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs
index 44eba42c..71acf39d 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs
@@ -118,6 +118,9 @@ public abstract class StructDeclarationTest : PInvokeGeneratorTest
[Fact]
public abstract Task InheritanceTest();
+ [Fact]
+ public abstract Task InheritanceWithNativeInheritanceAttributeTest();
+
[Theory]
[InlineData("double", "double", 10, 5)]
[InlineData("short", "short", 10, 5)]
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs
index 452dec2e..9f213f69 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs
@@ -71,5 +71,8 @@ public abstract class VarDeclarationTest : PInvokeGeneratorTest
[Fact]
public abstract Task UncheckedReinterpretCastMacroTest();
+
+ [Fact]
+ public abstract Task MultidimensionlArrayTest();
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs
index af1dfceb..877fdd72 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs
@@ -473,6 +473,82 @@ public int GetType(int objA, int objB)
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System;
+using System.Runtime.InteropServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public Vtbl* lpVtbl;
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType(MyStruct* pThis, int obj);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType1(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType2(MyStruct* pThis, int objA, int objB);
+
+ public int GetType(int obj)
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, obj);
+ }}
+ }}
+
+ public new int GetType()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis);
+ }}
+ }}
+
+ public int GetType(int objA, int objB)
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, objA, objB);
+ }}
+ }}
+
+ public partial struct Vtbl
+ {{
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int, int)" : "int (int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "new ")}IntPtr GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "2" : "")};
+
+ [NativeTypeName(""int ()"")]
+ public IntPtr GetType1;
+
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int)" : "int (int, int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "new " : "")}IntPtr GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "2")};
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
+ }
+
public override Task OperatorTest()
{
var inputContents = @"struct MyStruct
@@ -800,5 +876,96 @@ public int MyInt32Method()
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System;
+using System.Runtime.InteropServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public void** lpVtbl;
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate void _MyVoidMethod(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ [return: NativeTypeName(""char"")]
+ public delegate sbyte _MyInt8Method(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _MyInt32Method(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ [return: NativeTypeName(""void *"")]
+ public delegate void* _MyVoidStarMethod(MyStruct* pThis);
+
+ [VtblIndex(0)]
+ public void MyVoidMethod()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(1)]
+ [return: NativeTypeName(""char"")]
+ public sbyte MyInt8Method()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(2)]
+ public int MyInt32Method()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(3)]
+ [return: NativeTypeName(""void *"")]
+ public void* MyVoidStarMethod()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis);
+ }}
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs
index 1457e603..f74bf6a5 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs
@@ -423,7 +423,7 @@ public unsafe ref MyStruct this[int index]
{{
get
{{
- fixed (MyStruct* pThis = &e0)
+ fixed (MyStruct* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
@@ -747,6 +747,61 @@ public partial struct MyStruct2
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"namespace ClangSharp.Test
+{
+ public partial struct MyStruct1A
+ {
+ public int x;
+
+ public int y;
+ }
+
+ public partial struct MyStruct1B
+ {
+ public int x;
+
+ public int y;
+ }
+
+ [NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
+ [NativeInheritance(""MyStruct1B"")]
+ public partial struct MyStruct2
+ {
+ public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
+
+ public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
+
+ public int z;
+
+ public int w;
+ }
+}
+";
+
+ return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs
index 4c175609..e62d14d5 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs
@@ -465,7 +465,7 @@ public unsafe ref MyUnion this[int index]
{{
get
{{
- fixed (MyUnion* pThis = &e0)
+ fixed (MyUnion* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs
index f9d3f01e..85ff204a 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs
@@ -267,6 +267,35 @@ public static unsafe partial class Methods
public static readonly int* Macro1 = unchecked((int*)(-1));
}}
}}
+";
+
+ return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"namespace ClangSharp.Test
+{{
+ public static partial class Methods
+ {{
+ [NativeTypeName(""const int [2][2]"")]
+ public static int[][] MyArray = new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }};
+ }}
+}}
";
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs
index 82fef42d..a4d02349 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs
@@ -473,6 +473,82 @@ public int GetType(int objA, int objB)
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System;
+using System.Runtime.InteropServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public Vtbl* lpVtbl;
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType(MyStruct* pThis, int obj);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType1(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _GetType2(MyStruct* pThis, int objA, int objB);
+
+ public int GetType(int obj)
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, obj);
+ }}
+ }}
+
+ public new int GetType()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis);
+ }}
+ }}
+
+ public int GetType(int objA, int objB)
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, objA, objB);
+ }}
+ }}
+
+ public partial struct Vtbl
+ {{
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int, int)" : "int (int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "new ")}IntPtr GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "2" : "")};
+
+ [NativeTypeName(""int ()"")]
+ public IntPtr GetType1;
+
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int)" : "int (int, int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "new " : "")}IntPtr GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "2")};
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
+ }
+
public override Task OperatorTest()
{
var inputContents = @"struct MyStruct
@@ -800,5 +876,96 @@ public int MyInt32Method()
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System;
+using System.Runtime.InteropServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public void** lpVtbl;
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate void _MyVoidMethod(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ [return: NativeTypeName(""char"")]
+ public delegate sbyte _MyInt8Method(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ public delegate int _MyInt32Method(MyStruct* pThis);
+
+ [UnmanagedFunctionPointer(CallingConvention.{callConv})]
+ [return: NativeTypeName(""void *"")]
+ public delegate void* _MyVoidStarMethod(MyStruct* pThis);
+
+ [VtblIndex(0)]
+ public void MyVoidMethod()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(1)]
+ [return: NativeTypeName(""char"")]
+ public sbyte MyInt8Method()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(2)]
+ public int MyInt32Method()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis);
+ }}
+ }}
+
+ [VtblIndex(3)]
+ [return: NativeTypeName(""void *"")]
+ public void* MyVoidStarMethod()
+ {{
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis);
+ }}
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs
index 668b409d..4bb258b9 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs
@@ -427,7 +427,7 @@ public unsafe ref MyStruct this[int index]
{{
get
{{
- fixed (MyStruct* pThis = &e0)
+ fixed (MyStruct* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
@@ -751,6 +751,61 @@ public partial struct MyStruct2
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"namespace ClangSharp.Test
+{
+ public partial struct MyStruct1A
+ {
+ public int x;
+
+ public int y;
+ }
+
+ public partial struct MyStruct1B
+ {
+ public int x;
+
+ public int y;
+ }
+
+ [NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
+ [NativeInheritance(""MyStruct1B"")]
+ public partial struct MyStruct2
+ {
+ public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
+
+ public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
+
+ public int z;
+
+ public int w;
+ }
+}
+";
+
+ return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs
index 220865a9..70eaa389 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs
@@ -472,7 +472,7 @@ public unsafe ref MyUnion this[int index]
{{
get
{{
- fixed (MyUnion* pThis = &e0)
+ fixed (MyUnion* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs
index d1a3f7a1..36cb1ea5 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs
@@ -274,6 +274,35 @@ public static unsafe partial class Methods
public static readonly int* Macro1 = unchecked((int*)(-1));
}}
}}
+";
+
+ return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"namespace ClangSharp.Test
+{{
+ public static partial class Methods
+ {{
+ [NativeTypeName(""const int [2][2]"")]
+ public static int[][] MyArray = new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }};
+ }}
+}}
";
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs
index c7ef3964..2dce96ea 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs
@@ -419,15 +419,13 @@ public override Task NewKeywordVirtualTest()
};";
var callConv = "Cdecl";
-
+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
{
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -435,34 +433,82 @@ public unsafe partial struct MyStruct
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType(MyStruct* pThis, int obj);
+ public int GetType(int obj)
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ }}
+
+ public new int GetType()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType1(MyStruct* pThis);
+ public int GetType(int objA, int objB)
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ }}
+ }}
+}}
+";
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType2(MyStruct* pThis, int objA, int objB);
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public Vtbl* lpVtbl;
public int GetType(int obj)
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), obj);
}}
public new int GetType()
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this));
}}
public int GetType(int objA, int objB)
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ }}
+
+ public partial struct Vtbl
+ {{
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int, int)" : "int (int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "new ")}delegate* unmanaged[{callConv}] GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "2" : "")};
+
+ [NativeTypeName(""int ()"")]
+ public delegate* unmanaged[{callConv}] GetType1;
+
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int)" : "int (int, int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "new " : "")}delegate* unmanaged[{callConv}] GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "2")};
}}
}}
}}
";
- return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
}
public override Task OperatorTest()
@@ -730,9 +776,7 @@ virtual char MyInt8Method()
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -740,46 +784,96 @@ public unsafe partial struct MyStruct
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyVoidMethod(MyStruct* pThis);
+ public void MyVoidMethod()
+ {{
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
[return: NativeTypeName(""char"")]
- public delegate sbyte _MyInt8Method(MyStruct* pThis);
+ public sbyte MyInt8Method()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _MyInt32Method(MyStruct* pThis);
+ public int MyInt32Method()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
[return: NativeTypeName(""void *"")]
- public delegate void* _MyVoidStarMethod(MyStruct* pThis);
+ public void* MyVoidStarMethod()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public void** lpVtbl;
+
+ [VtblIndex(0)]
public void MyVoidMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(1)]
[return: NativeTypeName(""char"")]
public sbyte MyInt8Method()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(2)]
public int MyInt32Method()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(3)]
[return: NativeTypeName(""void *"")]
public void* MyVoidStarMethod()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
}}
}}
";
- return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
}
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationBodyImportTest.cs
index 232892fd..3c28d3fa 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationBodyImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationBodyImportTest.cs
@@ -503,9 +503,7 @@ struct MyStructB : MyStructA { };
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -513,12 +511,9 @@ public unsafe partial struct MyStructA
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyMethod(MyStructA* pThis);
-
public void MyMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
}}
}}
@@ -527,12 +522,9 @@ public unsafe partial struct MyStructB
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyMethod(MyStructB* pThis);
-
public void MyMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
}}
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs
index e2f632b0..d3650eea 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs
@@ -49,15 +49,14 @@ public override Task FunctionPointerParameterTest()
{
var inputContents = @"void MyFunction(void (*callback)());";
- var expectedOutputContents = @"using System;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = @"using System.Runtime.InteropServices;
namespace ClangSharp.Test
{
- public static partial class Methods
+ public static unsafe partial class Methods
{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern void MyFunction([NativeTypeName(""void (*)()"")] IntPtr callback);
+ public static extern void MyFunction([NativeTypeName(""void (*)()"")] delegate* unmanaged[Cdecl] callback);
}
}
";
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs
index 6bb7fff1..128a4654 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs
@@ -10,14 +10,7 @@ public override Task BasicTest()
{
var inputContents = @"typedef void (*Callback)();";
- var expectedOutputContents = @"using System.Runtime.InteropServices;
-
-namespace ClangSharp.Test
-{
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void Callback();
-}
-";
+ var expectedOutputContents = "";
return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs
index 229ae277..8920de91 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs
@@ -432,7 +432,7 @@ public ref MyStruct this[int index]
}}
}}
- public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0, 24);
+ public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
}}
}}
}}
@@ -755,6 +755,61 @@ public partial struct MyStruct2
return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"namespace ClangSharp.Test
+{
+ public partial struct MyStruct1A
+ {
+ public int x;
+
+ public int y;
+ }
+
+ public partial struct MyStruct1B
+ {
+ public int x;
+
+ public int y;
+ }
+
+ [NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
+ [NativeInheritance(""MyStruct1B"")]
+ public partial struct MyStruct2
+ {
+ public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
+
+ public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
+
+ public int z;
+
+ public int w;
+ }
+}
+";
+
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs
index c94c888f..3e511320 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs
@@ -471,7 +471,7 @@ public ref MyUnion this[int index]
}}
}}
- public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0, 24);
+ public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
}}
}}
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs
index 4fb0dca1..646f01e8 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs
@@ -181,14 +181,12 @@ public override Task UncheckedConversionMacroTest()
var inputContents = $@"#define MyMacro1 (long)0x80000000L
#define MyMacro2 (int)0x80000000";
- var expectedOutputContents = $@"using System;
-
-namespace ClangSharp.Test
+ var expectedOutputContents = $@"namespace ClangSharp.Test
{{
public static partial class Methods
{{
[NativeTypeName(""#define MyMacro1 (long)0x80000000L"")]
- public const IntPtr MyMacro1 = (IntPtr)(0x80000000);
+ public const nint MyMacro1 = unchecked((nint)(0x80000000));
[NativeTypeName(""#define MyMacro2 (int)0x80000000"")]
public const int MyMacro2 = unchecked((int)(0x80000000));
@@ -222,14 +220,12 @@ public override Task UncheckedConversionMacroTest2()
#define MyMacro2(n) MyMacro1(1, 2, n)
#define MyMacro3 MyMacro2(3)";
- var expectedOutputContents = $@"using System;
-
-namespace ClangSharp.Test
+ var expectedOutputContents = $@"namespace ClangSharp.Test
{{
public static partial class Methods
{{
[NativeTypeName(""#define MyMacro3 MyMacro2(3)"")]
- public const int MyMacro3 = unchecked((int)(((UIntPtr)(1) << 31) | ((UIntPtr)(2) << 16) | ((UIntPtr)(3))));
+ public const int MyMacro3 = unchecked((int)(((nuint)(1) << 31) | ((nuint)(2) << 16) | ((nuint)(3))));
}}
}}
";
@@ -267,6 +263,35 @@ public static unsafe partial class Methods
public static readonly int* Macro1 = unchecked((int*)(-1));
}}
}}
+";
+
+ return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"namespace ClangSharp.Test
+{{
+ public static partial class Methods
+ {{
+ [NativeTypeName(""const int [2][2]"")]
+ public static int[][] MyArray = new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }};
+ }}
+}}
";
return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs
index 9478c113..5362d7a7 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs
@@ -425,9 +425,7 @@ public override Task NewKeywordVirtualTest()
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -435,34 +433,82 @@ public unsafe partial struct MyStruct
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType(MyStruct* pThis, int obj);
+ public int GetType(int obj)
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ }}
+
+ public new int GetType()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
+
+ public int GetType(int objA, int objB)
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ }}
+ }}
+}}
+";
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType1(MyStruct* pThis);
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _GetType2(MyStruct* pThis, int objA, int objB);
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public Vtbl* lpVtbl;
public int GetType(int obj)
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), obj);
}}
public new int GetType()
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this));
}}
public int GetType(int objA, int objB)
{{
- return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ }}
+
+ public partial struct Vtbl
+ {{
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int, int)" : "int (int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "new ")}delegate* unmanaged[{callConv}] GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "2" : "")};
+
+ [NativeTypeName(""int ()"")]
+ public delegate* unmanaged[{callConv}] GetType1;
+
+ [NativeTypeName(""{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "int (int)" : "int (int, int)")}"")]
+ public {(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "new " : "")}delegate* unmanaged[{callConv}] GetType{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "2")};
}}
}}
}}
";
- return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
}
public override Task OperatorTest()
@@ -730,9 +776,7 @@ virtual char MyInt8Method()
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -740,46 +784,96 @@ public unsafe partial struct MyStruct
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyVoidMethod(MyStruct* pThis);
+ public void MyVoidMethod()
+ {{
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
[return: NativeTypeName(""char"")]
- public delegate sbyte _MyInt8Method(MyStruct* pThis);
+ public sbyte MyInt8Method()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate int _MyInt32Method(MyStruct* pThis);
+ public int MyInt32Method()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
[return: NativeTypeName(""void *"")]
- public delegate void* _MyVoidStarMethod(MyStruct* pThis);
+ public void* MyVoidStarMethod()
+ {{
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ }}
+ }}
+}}
+";
+
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
+
+namespace ClangSharp.Test
+{{
+ public unsafe partial struct MyStruct
+ {{
+ public void** lpVtbl;
+
+ [VtblIndex(0)]
public void MyVoidMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(1)]
[return: NativeTypeName(""char"")]
public sbyte MyInt8Method()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(2)]
public int MyInt32Method()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
+ [VtblIndex(3)]
[return: NativeTypeName(""void *"")]
public void* MyVoidStarMethod()
{{
- return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}])(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
}}
}}
}}
";
- return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
}
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationBodyImportTest.cs
index 73c542dd..2538ded1 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationBodyImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationBodyImportTest.cs
@@ -503,9 +503,7 @@ struct MyStructB : MyStructA { };
callConv = "ThisCall";
}
- var expectedOutputContents = $@"using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = $@"using System.Runtime.CompilerServices;
namespace ClangSharp.Test
{{
@@ -513,12 +511,9 @@ public unsafe partial struct MyStructA
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyMethod(MyStructA* pThis);
-
public void MyMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
}}
}}
@@ -527,12 +522,9 @@ public unsafe partial struct MyStructB
{{
public void** lpVtbl;
- [UnmanagedFunctionPointer(CallingConvention.{callConv})]
- public delegate void _MyMethod(MyStructB* pThis);
-
public void MyMethod()
{{
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}])(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
}}
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs
index 8966c96c..73824c49 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs
@@ -49,15 +49,14 @@ public override Task FunctionPointerParameterTest()
{
var inputContents = @"void MyFunction(void (*callback)());";
- var expectedOutputContents = @"using System;
-using System.Runtime.InteropServices;
+ var expectedOutputContents = @"using System.Runtime.InteropServices;
namespace ClangSharp.Test
{
- public static partial class Methods
+ public static unsafe partial class Methods
{
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern void MyFunction([NativeTypeName(""void (*)()"")] IntPtr callback);
+ public static extern void MyFunction([NativeTypeName(""void (*)()"")] delegate* unmanaged[Cdecl] callback);
}
}
";
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs
index f846c2d4..47e551b6 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs
@@ -10,14 +10,7 @@ public override Task BasicTest()
{
var inputContents = @"typedef void (*Callback)();";
- var expectedOutputContents = @"using System.Runtime.InteropServices;
-
-namespace ClangSharp.Test
-{
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void Callback();
-}
-";
+ var expectedOutputContents = "";
return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs
index 2696a825..218d24d0 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs
@@ -436,7 +436,7 @@ public ref MyStruct this[int index]
}}
}}
- public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0, 24);
+ public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
}}
}}
}}
@@ -759,6 +759,61 @@ public partial struct MyStruct2
return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"namespace ClangSharp.Test
+{
+ public partial struct MyStruct1A
+ {
+ public int x;
+
+ public int y;
+ }
+
+ public partial struct MyStruct1B
+ {
+ public int x;
+
+ public int y;
+ }
+
+ [NativeTypeName(""struct MyStruct2 : MyStruct1A, MyStruct1B"")]
+ [NativeInheritance(""MyStruct1B"")]
+ public partial struct MyStruct2
+ {
+ public MyStruct1A __AnonymousBase_ClangUnsavedFile_L13_C20;
+
+ public MyStruct1B __AnonymousBase_ClangUnsavedFile_L13_C32;
+
+ public int z;
+
+ public int w;
+ }
+}
+";
+
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs
index 788aef10..212d3a32 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs
@@ -477,7 +477,7 @@ public ref MyUnion this[int index]
}}
}}
- public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0, 24);
+ public Span AsSpan() => MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
}}
}}
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs
index 7eb43e84..c2acc8c9 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs
@@ -274,6 +274,35 @@ public static unsafe partial class Methods
public static readonly int* Macro1 = unchecked((int*)(-1));
}}
}}
+";
+
+ return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"namespace ClangSharp.Test
+{{
+ public static partial class Methods
+ {{
+ [NativeTypeName(""const int [2][2]"")]
+ public static int[][] MyArray = new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }};
+ }}
+}}
";
return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs
index 8c53f4fb..766344ea 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs
@@ -33,44 +33,44 @@ protected string EscapeXml(string value)
return new XText(value).ToString();
}
- protected Task ValidateGeneratedCSharpLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedCSharpLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.None, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedCSharpLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedCSharpLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedCSharpCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedCSharpCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null, [CallerFilePath] string filePath = "")
+ protected Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null, [CallerFilePath] string filePath = "")
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs, filePath);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs, filePath);
}
- protected Task ValidateGeneratedXmlLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedXmlLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedXmlCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedXmlCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
- protected Task ValidateGeneratedXmlCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
+ protected Task ValidateGeneratedXmlCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null)
{
- return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
+ return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs);
}
private async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorOutputMode outputMode, PInvokeGeneratorConfigurationOptions configOptions, string[] excludedNames, IReadOnlyDictionary remappedNames, IReadOnlyDictionary> withAttributes, IReadOnlyDictionary withCallConvs, IReadOnlyDictionary withLibraryPaths, string[] withSetLastErrors, IReadOnlyDictionary withTypes, IReadOnlyDictionary> withUsings, IEnumerable expectedDiagnostics, string libraryPath, string[] commandlineArgs, [CallerFilePath] string filePath = "")
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs
index 8002c7cb..58cd31b6 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs
@@ -556,6 +556,111 @@ public override Task NewKeywordVirtualTest()
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ Vtbl*
+
+
+ int
+
+ MyStruct*
+
+
+ int
+
+
+
+ int
+
+ MyStruct*
+
+
+
+ int
+
+ MyStruct*
+
+
+ int
+
+
+ int
+
+
+
+ int
+
+ int
+
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, obj);
+ }}
+
+
+
+ int
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis);
+ }}
+
+
+
+ int
+
+ int
+
+
+ int
+
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, objA, objB);
+ }}
+
+
+
+
+ IntPtr
+
+
+ IntPtr
+
+
+ IntPtr
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
+ }
+
public override Task OperatorTest()
{
var inputContents = @"struct MyStruct
@@ -929,5 +1034,104 @@ virtual char MyInt8Method()
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ void**
+
+
+ void
+
+ MyStruct*
+
+
+
+ sbyte
+
+ MyStruct*
+
+
+
+ int
+
+ MyStruct*
+
+
+
+ void*
+
+ MyStruct*
+
+
+
+ void
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis);
+ }}
+
+
+
+ sbyte
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis);
+ }}
+
+
+
+ int
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis);
+ }}
+
+
+
+ void*
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis);
+ }}
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs
index 03d6176b..cbf25abb 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs
@@ -441,7 +441,7 @@ struct MyOtherStruct
int
- fixed (MyStruct* pThis = &e0)
+ fixed (MyStruct* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
@@ -794,6 +794,67 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ MyStruct1A
+
+
+ MyStruct1B
+
+
+ int
+
+
+ int
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs
index de84f605..d2560c12 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs
@@ -443,7 +443,7 @@ union MyOtherUnion
int
- fixed (MyUnion* pThis = &e0)
+ fixed (MyUnion* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs
index f43170a7..cd8354e2 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs
@@ -345,6 +345,40 @@ public override Task UncheckedReinterpretCastMacroTest()
+";
+
+ return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"
+
+
+
+
+ int[][]
+
+ new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }}
+
+
+
+
+
";
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs
index 9ab21ffc..1e3385b5 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs
@@ -556,6 +556,111 @@ public override Task NewKeywordVirtualTest()
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ Vtbl*
+
+
+ int
+
+ MyStruct*
+
+
+ int
+
+
+
+ int
+
+ MyStruct*
+
+
+
+ int
+
+ MyStruct*
+
+
+ int
+
+
+ int
+
+
+
+ int
+
+ int
+
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, obj);
+ }}
+
+
+
+ int
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis);
+ }}
+
+
+
+ int
+
+ int
+
+
+ int
+
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, objA, objB);
+ }}
+
+
+
+
+ IntPtr
+
+
+ IntPtr
+
+
+ IntPtr
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
+ }
+
public override Task OperatorTest()
{
var inputContents = @"struct MyStruct
@@ -929,5 +1034,104 @@ virtual char MyInt8Method()
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ void**
+
+
+ void
+
+ MyStruct*
+
+
+
+ sbyte
+
+ MyStruct*
+
+
+
+ int
+
+ MyStruct*
+
+
+
+ void*
+
+ MyStruct*
+
+
+
+ void
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis);
+ }}
+
+
+
+ sbyte
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis);
+ }}
+
+
+
+ int
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis);
+ }}
+
+
+
+ void*
+
+ fixed (MyStruct* pThis = &this)
+ {{
+ return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis);
+ }}
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs
index f4259655..1cd88479 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs
@@ -447,7 +447,7 @@ struct MyOtherStruct
int
- fixed (MyStruct* pThis = &e0)
+ fixed (MyStruct* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
@@ -800,6 +800,67 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ MyStruct1A
+
+
+ MyStruct1B
+
+
+ int
+
+
+ int
+
+
+
+
+";
+
+ return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs
index 97e430bd..c269a363 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs
@@ -449,7 +449,7 @@ union MyOtherUnion
int
- fixed (MyUnion* pThis = &e0)
+ fixed (MyUnion* pThis = &e0_0_0_0)
{{
return ref pThis[index];
}}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs
index 01e281cc..95158151 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs
@@ -365,6 +365,40 @@ public override Task UncheckedReinterpretCastMacroTest()
+";
+
+ return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"
+
+
+
+
+ int[][]
+
+ new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }}
+
+
+
+
+
";
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs
index fde606cc..18f8a882 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs
@@ -472,7 +472,7 @@ public override Task NewKeywordVirtualTest()
};";
var callConv = "Cdecl";
-
+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
{
callConv = "ThisCall";
@@ -485,46 +485,77 @@ public override Task NewKeywordVirtualTest()
void**
-
+
int
-
- MyStruct*
-
int
-
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int, int>)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+
+
+
int
-
- MyStruct*
-
-
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
int
-
- MyStruct*
-
int
int
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int, int, int>)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ Vtbl*
+
int
int
- return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), obj);
int
- return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this));
@@ -536,15 +567,26 @@ public override Task NewKeywordVirtualTest()
int
- return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int, int{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", int" : "")}>
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int>
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int, int{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : ", int")}>
+
+
";
- return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
}
public override Task OperatorTest()
@@ -853,52 +895,28 @@ virtual char MyInt8Method()
void**
-
- void
-
- MyStruct*
-
-
-
- sbyte
-
- MyStruct*
-
-
-
- int
-
- MyStruct*
-
-
-
- void*
-
- MyStruct*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStruct*, void>)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
sbyte
- return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, sbyte>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
int
- return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
void*
- return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, void*>)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
@@ -908,5 +926,68 @@ virtual char MyInt8Method()
return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ void**
+
+
+ void
+
+ ((delegate* unmanaged[{callConv}]<MyStruct*, void>)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ sbyte
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, sbyte>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ int
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ void*
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, void*>)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs
index c1f4f4bf..558e0130 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs
@@ -592,16 +592,10 @@ struct MyStructB : MyStructA { };
void**
-
- void
-
- MyStructA*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStructA*, void>)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
@@ -609,16 +603,10 @@ struct MyStructB : MyStructA { };
void**
-
- void
-
- MyStructB*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStructB*, void>)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs
index 14b62f38..77846752 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs
@@ -56,10 +56,10 @@ public override Task FunctionPointerParameterTest()
-
+
void
- IntPtr
+ delegate* unmanaged[Cdecl]<void>
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs
index 00312581..a44ce5b5 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs
@@ -10,15 +10,7 @@ public override Task BasicTest()
{
var inputContents = @"typedef void (*Callback)();";
- var expectedOutputContents = @"
-
-
-
- void
-
-
-
-";
+ var expectedOutputContents = "";
return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs
index 9cf8f55b..d4a894ed 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs
@@ -447,7 +447,7 @@ struct MyOtherStruct
Span<MyStruct>
- MemoryMarshal.CreateSpan(ref e0, 24);
+ MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
@@ -798,6 +798,67 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ MyStruct1A
+
+
+ MyStruct1B
+
+
+ int
+
+
+ int
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs
index b974b9d1..e7078dcc 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs
@@ -449,7 +449,7 @@ union MyOtherUnion
Span<MyUnion>
- MemoryMarshal.CreateSpan(ref e0, 24);
+ MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs
index b3283f82..42cae630 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs
@@ -224,9 +224,13 @@ public override Task UncheckedConversionMacroTest()
- IntPtr
+ nint
- (IntPtr)(0x80000000)
+
+
+ (nint)(0x80000000)
+
+
@@ -287,7 +291,7 @@ public override Task UncheckedConversionMacroTest2()
int
- ((int)(((UIntPtr)(1) << 31) | ((UIntPtr)(2) << 16) | ((UIntPtr)(3))))
+ ((int)(((nuint)(1) << 31) | ((nuint)(2) << 16) | ((nuint)(3))))
@@ -345,6 +349,40 @@ public override Task UncheckedReinterpretCastMacroTest()
+";
+
+ return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"
+
+
+
+
+ int[][]
+
+ new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }}
+
+
+
+
+
";
return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs
index 81931502..055a97a8 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs
@@ -485,46 +485,77 @@ public override Task NewKeywordVirtualTest()
void**
-
+
int
-
- MyStruct*
-
int
-
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int, int>)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+
+
+
int
-
- MyStruct*
-
-
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
int
-
- MyStruct*
-
int
int
-
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int, int, int>)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task NewKeywordVirtualWithExplicitVtblTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual int GetType(int obj) = 0;
+ virtual int GetType() = 0;
+ virtual int GetType(int objA, int objB) = 0;
+};";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ Vtbl*
+
int
int
- return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0)}]))((MyStruct*)Unsafe.AsPointer(ref this), obj);
+ return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), obj);
int
- return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this));
@@ -536,15 +567,26 @@ public override Task NewKeywordVirtualTest()
int
- return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0 : 2)}]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+ return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), objA, objB);
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int, int{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", int" : "")}>
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int>
+
+
+ delegate* unmanaged[{callConv}]<MyStruct*, int, int{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : ", int")}>
+
+
";
- return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls);
}
public override Task OperatorTest()
@@ -853,52 +895,28 @@ virtual char MyInt8Method()
void**
-
- void
-
- MyStruct*
-
-
-
- sbyte
-
- MyStruct*
-
-
-
- int
-
- MyStruct*
-
-
-
- void*
-
- MyStruct*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStruct*, void>)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
sbyte
- return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, sbyte>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
int
- return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
void*
- return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, void*>)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
@@ -908,5 +926,68 @@ virtual char MyInt8Method()
return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+
+ public override Task VirtualWithVtblIndexAttributeTest()
+ {
+ var inputContents = @"struct MyStruct
+{
+ virtual void MyVoidMethod() = 0;
+
+ virtual char MyInt8Method()
+ {
+ return 0;
+ }
+
+ virtual int MyInt32Method();
+
+ virtual void* MyVoidStarMethod() = 0;
+};
+";
+
+ var callConv = "Cdecl";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess)
+ {
+ callConv = "ThisCall";
+ }
+
+ var expectedOutputContents = $@"
+
+
+
+
+ void**
+
+
+ void
+
+ ((delegate* unmanaged[{callConv}]<MyStruct*, void>)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ sbyte
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, sbyte>)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ int
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, int>)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+ void*
+
+ return ((delegate* unmanaged[{callConv}]<MyStruct*, void*>)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this));
+
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
+ }
}
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs
index c4f811a4..f19bfe4c 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs
@@ -592,16 +592,10 @@ struct MyStructB : MyStructA { };
void**
-
- void
-
- MyStructA*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStructA*, void>)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this));
@@ -609,16 +603,10 @@ struct MyStructB : MyStructA { };
void**
-
- void
-
- MyStructB*
-
-
void
- Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
+ ((delegate* unmanaged[{callConv}]<MyStructB*, void>)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this));
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs
index 55a21869..ee6a6fda 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs
@@ -56,10 +56,10 @@ public override Task FunctionPointerParameterTest()
-
+
void
- IntPtr
+ delegate* unmanaged[Cdecl]<void>
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs
index 8db6f1fa..2c9214b9 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs
@@ -10,15 +10,7 @@ public override Task BasicTest()
{
var inputContents = @"typedef void (*Callback)();";
- var expectedOutputContents = @"
-
-
-
- void
-
-
-
-";
+ var expectedOutputContents = "";
return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs
index a69c2d25..ac118e4d 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs
@@ -453,7 +453,7 @@ struct MyOtherStruct
Span<MyStruct>
- MemoryMarshal.CreateSpan(ref e0, 24);
+ MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
@@ -804,6 +804,67 @@ struct MyStruct2 : MyStruct1A, MyStruct1B
return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
+ public override Task InheritanceWithNativeInheritanceAttributeTest()
+ {
+ var inputContents = @"struct MyStruct1A
+{
+ int x;
+ int y;
+};
+
+struct MyStruct1B
+{
+ int x;
+ int y;
+};
+
+struct MyStruct2 : MyStruct1A, MyStruct1B
+{
+ int z;
+ int w;
+};
+";
+
+ var expectedOutputContents = @"
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ int
+
+
+ int
+
+
+
+
+ MyStruct1A
+
+
+ MyStruct1B
+
+
+ int
+
+
+ int
+
+
+
+
+";
+
+ return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateNativeInheritanceAttribute);
+ }
+
public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column)
{
var inputContents = $@"typedef union {{
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs
index 77078d67..85449f76 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs
@@ -455,7 +455,7 @@ union MyOtherUnion
Span<MyUnion>
- MemoryMarshal.CreateSpan(ref e0, 24);
+ MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs
index 957a9aa0..9e4c55b1 100644
--- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs
+++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs
@@ -365,6 +365,40 @@ public override Task UncheckedReinterpretCastMacroTest()
+";
+
+ return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
+ }
+
+ public override Task MultidimensionlArrayTest()
+ {
+ var inputContents = $@"const int MyArray[2][2] = {{ {{ 0, 1 }}, {{ 2, 3 }} }};";
+
+ var expectedOutputContents = $@"
+
+
+
+
+ int[][]
+
+ new int[2][]
+ {{
+ new int[2]
+ {{
+ 0,
+ 1,
+ }},
+ new int[2]
+ {{
+ 2,
+ 3,
+ }},
+ }}
+
+
+
+
+
";
return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents);