From a7b46667491f86318bad70d9505c8f57cee630e3 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Tue, 30 Apr 2024 12:45:34 -0700 Subject: [PATCH] Fix crash when using a default argument from a base template --- .../PInvokeGenerator.VisitDecl.cs | 19 +++++---- .../ClangSharp/Cursors/Decls/ParmVarDecl.cs | 4 ++ .../Cursors/Exprs/CXXDefaultArgExpr.cs | 2 - .../Base/CXXMethodDeclarationTest.cs | 5 +++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 34 +++++++++++++++ .../CXXMethodDeclarationTest.cs | 41 ++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 42 +++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 42 +++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 42 +++++++++++++++++++ .../XmlLatestUnix/CXXMethodDeclarationTest.cs | 42 +++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 42 +++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 40 ++++++++++++++++++ .../CXXMethodDeclarationTest.cs | 41 ++++++++++++++++++ 20 files changed, 623 insertions(+), 11 deletions(-) diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 85ecc322..49067445 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -1253,10 +1253,13 @@ void ForFunctionDecl(ParmVarDecl parmVarDecl, FunctionDecl functionDecl) var handledDefaultArg = false; var isExprDefaultValue = false; + var defaultArg = (parmVarDecl.HasDefaultArg && !parmVarDecl.HasUnparsedDefaultArg) ? + (parmVarDecl.HasUninstantiatedDefaultArg ? parmVarDecl.UninstantiatedDefaultArg : parmVarDecl.DefaultArg) : + null; - if (parmVarDecl.HasDefaultArg) + if (defaultArg != null) { - isExprDefaultValue = IsDefaultValue(parmVarDecl.DefaultArg); + isExprDefaultValue = IsDefaultValue(defaultArg); if ((_outputBuilder is CSharpOutputBuilder csharpOutputBuilder) && (_config.WithTransparentStructs.ContainsKey(typeName) || parameters.Skip(index).Any((parmVarDecl) => { var type = parmVarDecl.Type; @@ -1264,19 +1267,17 @@ void ForFunctionDecl(ParmVarDecl parmVarDecl, FunctionDecl functionDecl) return _config.WithTransparentStructs.ContainsKey(typeName); }))) { - desc.CustomAttrGeneratorData = (parmVarDecl, this, csharpOutputBuilder, isExprDefaultValue ? null : parmVarDecl.DefaultArg); + desc.CustomAttrGeneratorData = (parmVarDecl, this, csharpOutputBuilder, isExprDefaultValue ? null : defaultArg); handledDefaultArg = true; } } _outputBuilder.BeginParameter(in desc); - if (parmVarDecl.HasDefaultArg && !handledDefaultArg) + if (defaultArg != null && !handledDefaultArg) { _outputBuilder.BeginParameterDefault(); - var defaultArg = parmVarDecl.DefaultArg; - if (IsTypePointerOrReference(parmVarDecl) && (defaultArg.Handle.Evaluate.Kind == CXEval_UnExposed)) { if (!isExprDefaultValue) @@ -1290,7 +1291,7 @@ void ForFunctionDecl(ParmVarDecl parmVarDecl, FunctionDecl functionDecl) } else { - Visit(parmVarDecl.DefaultArg); + Visit(defaultArg); } _outputBuilder.EndParameterDefault(); @@ -1341,10 +1342,10 @@ void ForTypedefDecl(ParmVarDecl parmVarDecl, TypedefDecl typedefDecl) _outputBuilder.BeginParameter(in desc); - if (parmVarDecl.HasDefaultArg) + if (parmVarDecl.HasDefaultArg && !parmVarDecl.HasUnparsedDefaultArg) { _outputBuilder.BeginParameterDefault(); - Visit(parmVarDecl.DefaultArg); + Visit(parmVarDecl.HasUninstantiatedDefaultArg ? parmVarDecl.UninstantiatedDefaultArg : parmVarDecl.DefaultArg); _outputBuilder.EndParameterDefault(); } diff --git a/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs b/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs index 99c5b809..d8d64f90 100644 --- a/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs @@ -28,6 +28,10 @@ internal ParmVarDecl(CXCursor handle) : base(handle, CXCursor_ParmDecl, CX_DeclK public bool HasDefaultArg => Handle.HasDefaultArg; + public bool HasUnparsedDefaultArg => Handle.HasUnparsedDefaultArg; + + public bool HasUninstantiatedDefaultArg => Handle.HasUninstantiatedDefaultArg; + public bool HasInheritedDefaultArg => Handle.HasInheritedDefaultArg; public Type OriginalType => _originalType.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs index 53a94e41..c4180a7d 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs @@ -21,8 +21,6 @@ internal CXXDefaultArgExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExp _usedContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UsedContext) as IDeclContext); } - public Expr Expr => Param.DefaultArg; - public ParmVarDecl Param => _param.Value; public IDeclContext? UsedContext => _usedContext.Value; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs index a553add5..05f77d4c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs @@ -16,6 +16,9 @@ public abstract class CXXMethodDeclarationTest : PInvokeGeneratorTest [Test] public Task ConversionTest() => ConversionTestImpl(); + [Test] + public Task DefaultParameterInheritedFromTemplateTest() => DefaultParameterInheritedFromTemplateTestImpl(); + [Test] public Task DestructorTest() => DestructorTestImpl(); @@ -107,6 +110,8 @@ public static int buf_close(void* pContext) protected abstract Task ConversionTestImpl(); + protected abstract Task DefaultParameterInheritedFromTemplateTestImpl(); + protected abstract Task DestructorTestImpl(); protected abstract Task InstanceTestImpl(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs index 92ec9bb7..afc4704c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs index 4350c0ea..14249777 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/CXXMethodDeclarationTest.cs index 38b5dba5..47e77d51 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpDefaultUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpDefaultUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/CXXMethodDeclarationTest.cs index bf88b54a..01f769a5 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs index 592d6d39..9ac0558a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs index 6ab93f9a..e37b13e8 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/CXXMethodDeclarationTest.cs index bd0e1628..e9f3cb58 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/CXXMethodDeclarationTest.cs index be7f7e23..28f1de68 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/CXXMethodDeclarationTest.cs @@ -125,6 +125,40 @@ public int ToInt32() return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + [NativeTypeName(""struct MyStruct : MyTemplate"")] + public unsafe partial struct MyStruct + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.ThisCall, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern int* DoWork(MyStruct* pThis, int* value = null); + }} +}} +"; + + return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs index ca361054..0403f89d 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs @@ -165,6 +165,47 @@ operator int() return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs index 8f1e18f8..20c1ee5c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs @@ -165,6 +165,48 @@ operator int() return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/CXXMethodDeclarationTest.cs index 816ed4b0..a27fcb0a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/CXXMethodDeclarationTest.cs @@ -165,6 +165,48 @@ operator int() return ValidateGeneratedXmlDefaultUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlDefaultUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/CXXMethodDeclarationTest.cs index eb5e35ee..68d12ca2 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/CXXMethodDeclarationTest.cs @@ -165,6 +165,48 @@ operator int() return ValidateGeneratedXmlDefaultWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlDefaultWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs index 3f960b1c..6f9e9e76 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs @@ -165,6 +165,48 @@ operator int() return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs index bfe93675..56aa6a01 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs @@ -165,6 +165,48 @@ operator int() return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/CXXMethodDeclarationTest.cs index 6a627df3..6f753d62 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/CXXMethodDeclarationTest.cs @@ -165,6 +165,46 @@ operator int() return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8$MyTemplateDoWorkEv" : "_ZN10MyTemplateIiE6DoWorkEPi"; + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + return ValidateGeneratedXmlPreviewUnixBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/CXXMethodDeclarationTest.cs index b07fe0d8..e942b31a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/CXXMethodDeclarationTest.cs @@ -165,6 +165,47 @@ operator int() return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents); } + protected override Task DefaultParameterInheritedFromTemplateTestImpl() + { + // NOTE: This is a regression test where a struct inherits a function from a template with a default parameter. + const string InputContents = @"template +struct MyTemplate +{ + int* DoWork(int* value = nullptr) + { + return value; + } +}; + +struct MyStruct : public MyTemplate +{}; +"; + + var entryPoint = Environment.Is64BitProcess ? "?DoWork@?$MyTemplate@H@@QEAAPEAHPEAH@Z" : "?DoWork@?$MyTemplate@H@@QEAPEHPEH@Z"; + + var expectedOutputContents = $@" + + + + + int* + + MyStruct* + + + int* + + null + + + + + + +"; + return ValidateGeneratedXmlPreviewWindowsBindingsAsync(InputContents, expectedOutputContents); + } + protected override Task DestructorTestImpl() { var inputContents = @"struct MyStruct