From e60cd134a6794edf5e31756d4f8a0053a569a53a Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 13 Jul 2026 01:30:08 -0700 Subject: [PATCH] Don't crash on undefined function-like macros An undefined function-like macro used in another macro's body (e.g. `#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)` where `TESTRESULT_FROM_WIN32` is not defined) synthesized a `ClangSharpMacro_` `VarDecl` whose initializer resolved to a plain `Stmt` rather than an `Expr`. `VarDecl.InitFactory` hard-cast the result via `GetOrCreate`, throwing `InvalidCastException`. Resolve the initializer via `GetOrCreate(...) as Expr` so a non-`Expr` initializer yields `null` instead of throwing, and have the macro handling in `VisitVarDecl` gracefully skip such a macro while emitting a warning diagnostic. Also warn, rather than silently skip, when the initializer resolves to a `RecoveryExpr`, which is how modern Clang represents these unresolved invocations. Fixes #222 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../PInvokeGenerator.VisitVarDecl.cs | 12 ++++++++++-- sources/ClangSharp/Cursors/Decls/VarDecl.cs | 2 +- .../Base/VarDeclarationTest.cs | 5 +++++ .../CSharpCompatibleUnix/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpCompatibleWindows/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpDefaultUnix/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpDefaultWindows/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpLatestUnix/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpLatestWindows/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpPreviewUnix/VarDeclarationTest.cs | 10 ++++++++++ .../CSharpPreviewWindows/VarDeclarationTest.cs | 10 ++++++++++ .../XmlCompatibleUnix/VarDeclarationTest.cs | 10 ++++++++++ .../XmlCompatibleWindows/VarDeclarationTest.cs | 10 ++++++++++ .../XmlDefaultUnix/VarDeclarationTest.cs | 10 ++++++++++ .../XmlDefaultWindows/VarDeclarationTest.cs | 10 ++++++++++ .../XmlLatestUnix/VarDeclarationTest.cs | 10 ++++++++++ .../XmlLatestWindows/VarDeclarationTest.cs | 10 ++++++++++ .../XmlPreviewUnix/VarDeclarationTest.cs | 10 ++++++++++ .../XmlPreviewWindows/VarDeclarationTest.cs | 10 ++++++++++ 19 files changed, 176 insertions(+), 3 deletions(-) diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitVarDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitVarDecl.cs index c70e8912..f5bc631a 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitVarDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitVarDecl.cs @@ -43,9 +43,16 @@ private void VisitVarDecl(VarDecl varDecl) var nativeName = GetCursorName(varDecl); if (nativeName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { - type = varDecl.Init.Type; nativeName = nativeName["ClangSharpMacro_".Length..]; isMacroDefinitionRecord = true; + + if (varDecl.Init is null) + { + AddDiagnostic(DiagnosticLevel.Warning, $"Macro definition '{nativeName}' could not be resolved to a supported expression. Generated bindings may be incomplete.", varDecl); + return; + } + + type = varDecl.Init.Type; } var accessSpecifier = GetAccessSpecifier(varDecl, matchStar: false); @@ -61,8 +68,9 @@ private void VisitVarDecl(VarDecl varDecl) return; } } - else if (IsStmtAsWritten(varDecl.Init, out var recoveryExpr, removeParens: true)) + else if (IsStmtAsWritten(varDecl.Init, out _, removeParens: true)) { + AddDiagnostic(DiagnosticLevel.Warning, $"Macro definition '{nativeName}' could not be resolved to a supported expression. Generated bindings may be incomplete.", varDecl); return; } } diff --git a/sources/ClangSharp/Cursors/Decls/VarDecl.cs b/sources/ClangSharp/Cursors/Decls/VarDecl.cs index 40e1fd24..2e383b12 100644 --- a/sources/ClangSharp/Cursors/Decls/VarDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/VarDecl.cs @@ -59,7 +59,7 @@ private protected unsafe VarDecl(CXCursor handle, CXCursorKind expectedCursorKin private static unsafe VarDecl InstantiatedFromStaticDataMemberFactory(VarDecl self) => self.TranslationUnit.GetOrCreate(self.Handle.InstantiatedFromMember); - private static unsafe Expr InitFactory(VarDecl self) => self.TranslationUnit.GetOrCreate(self.Handle.InitExpr); + private static unsafe Expr InitFactory(VarDecl self) => (self.TranslationUnit.GetOrCreate(self.Handle.InitExpr) as Expr)!; private static unsafe VarDecl DefinitionFactory(VarDecl self) => self.TranslationUnit.GetOrCreate(self.Handle.Definition); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs index 864cd583..2cc3ea7e 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs @@ -84,6 +84,9 @@ public abstract class VarDeclarationTest : PInvokeGeneratorTest [Test] public Task ConditionalDefineConstTest() => ConditionalDefineConstTestImpl(); + [Test] + public Task UndefinedFunctionLikeMacroTest() => UndefinedFunctionLikeMacroTestImpl(); + protected abstract Task BasicTestImpl(string nativeType, string expectedManagedType); protected abstract Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType); @@ -121,4 +124,6 @@ public abstract class VarDeclarationTest : PInvokeGeneratorTest protected abstract Task MultidimensionlArrayTestImpl(); protected abstract Task ConditionalDefineConstTestImpl(); + + protected abstract Task UndefinedFunctionLikeMacroTestImpl(); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs index 5bfb7be2..e1871e6d 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/VarDeclarationTest.cs @@ -398,4 +398,14 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs index fba485f7..33db4311 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/VarDeclarationTest.cs @@ -395,4 +395,14 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/VarDeclarationTest.cs index 4b06c22c..0433d111 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/VarDeclarationTest.cs @@ -397,4 +397,14 @@ public static partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/VarDeclarationTest.cs index 63d7d276..ab364807 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/VarDeclarationTest.cs @@ -395,4 +395,14 @@ public static partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs index 09a0fc74..dfc9e8de 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs @@ -397,4 +397,14 @@ public static partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs index cc9e2428..877351de 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/VarDeclarationTest.cs @@ -395,4 +395,14 @@ public static partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs index 1bad9672..3b4edf2f 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs @@ -399,4 +399,14 @@ public static partial class Methods return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/VarDeclarationTest.cs index 714c18ed..7e6e6028 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/VarDeclarationTest.cs @@ -395,4 +395,14 @@ public static partial class Methods return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs index 37103690..776932f8 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs index fc6e0f25..fcdace42 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/VarDeclarationTest.cs index f321d031..689bfe63 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/VarDeclarationTest.cs index cc815988..1345f4e7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs index 7092a765..3db3bb34 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs index 1c1ae4dc..ccb99e7c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs @@ -531,4 +531,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs index 84b87012..19dc457c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/VarDeclarationTest.cs index afe0fc7c..1c8c3fb6 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/VarDeclarationTest.cs @@ -530,4 +530,14 @@ protected override Task ConditionalDefineConstTestImpl() return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); } + + protected override Task UndefinedFunctionLikeMacroTestImpl() + { + var inputContents = @"#define ADDRESS_IN_USE TESTRESULT_FROM_WIN32(10048)"; + + var expectedOutputContents = ""; + var diagnostics = new Diagnostic[] { new Diagnostic(DiagnosticLevel.Warning, "Macro definition 'ADDRESS_IN_USE' could not be resolved to a supported expression. Generated bindings may be incomplete.", "Line 2, Column 12 in ClangUnsavedFile.h") }; + + return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, expectedDiagnostics: diagnostics); + } }