diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 99986beb..64cb5ff3 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -348,7 +348,7 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl) } contextNameParts.Push(EscapeName(contextNamePart)); - contextTypeParts.Push(GetRemappedTypeName(anonymousRecordDecl, context: null, anonymousRecordDecl.TypeForDecl, out string nativeTypeName)); + contextTypeParts.Push(GetRemappedTypeName(rootRecordDecl, context: null, rootRecordDecl.TypeForDecl, out string nativeTypeName)); if (!rootRecordDecl.IsAnonymousStructOrUnion) { diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index 12d4306c..cbf374eb 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -1007,6 +1007,11 @@ private void VisitMemberExpr(MemberExpr memberExpr) StopCSharpCode(); } + private void VisitNullStmt(NullStmt nullStmt) + { + // null statements are empty by definition, so nothing to do + } + private void VisitParenExpr(ParenExpr parenExpr) { var outputBuilder = StartCSharpCode(); @@ -1106,7 +1111,13 @@ private void VisitStmt(Stmt stmt) // case CX_StmtClass.CX_StmtClass_IndirectGotoStmt: // case CX_StmtClass.CX_StmtClass_MSDependentExistsStmt: - // case CX_StmtClass.CX_StmtClass_NullStmt: + + case CX_StmtClass.CX_StmtClass_NullStmt: + { + VisitNullStmt((NullStmt)stmt); + break; + } + // case CX_StmtClass.CX_StmtClass_OMPAtomicDirective: // case CX_StmtClass.CX_StmtClass_OMPBarrierDirective: // case CX_StmtClass.CX_StmtClass_OMPCancelDirective: diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index ee5b76e2..355747f3 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -275,42 +275,50 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s } } - if (_config.GenerateMacroBindings) + try { - var translationUnitHandle = translationUnit.Handle; + if (_config.GenerateMacroBindings) + { + var translationUnitHandle = translationUnit.Handle; - var file = translationUnitHandle.GetFile(_filePath); - var fileContents = translationUnitHandle.GetFileContents(file, out var size); + var file = translationUnitHandle.GetFile(_filePath); + var fileContents = translationUnitHandle.GetFileContents(file, out var size); #if NETCOREAPP - _fileContentsBuilder.Append(Encoding.UTF8.GetString(fileContents)); + _fileContentsBuilder.Append(Encoding.UTF8.GetString(fileContents)); #else - _fileContentsBuilder.Append(Encoding.UTF8.GetString(fileContents.ToArray())); + _fileContentsBuilder.Append(Encoding.UTF8.GetString(fileContents.ToArray())); #endif - foreach (var cursor in translationUnit.TranslationUnitDecl.CursorChildren) - { - if (cursor is PreprocessedEntity preprocessedEntity) + foreach (var cursor in translationUnit.TranslationUnitDecl.CursorChildren) { - VisitPreprocessedEntity(preprocessedEntity); + if (cursor is PreprocessedEntity preprocessedEntity) + { + VisitPreprocessedEntity(preprocessedEntity); + } } - } - var unsavedFileContents = _fileContentsBuilder.ToString(); - _fileContentsBuilder.Clear(); + var unsavedFileContents = _fileContentsBuilder.ToString(); + _fileContentsBuilder.Clear(); - using var unsavedFile = CXUnsavedFile.Create(_filePath, unsavedFileContents); - var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; + using var unsavedFile = CXUnsavedFile.Create(_filePath, unsavedFileContents); + var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; - translationFlags = _translationFlags & ~CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord; - var handle = CXTranslationUnit.Parse(IndexHandle, _filePath, _clangCommandLineArgs, unsavedFiles, translationFlags); + translationFlags = _translationFlags & ~CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord; + var handle = CXTranslationUnit.Parse(IndexHandle, _filePath, _clangCommandLineArgs, unsavedFiles, translationFlags); - using var nestedTranslationUnit = TranslationUnit.GetOrCreate(handle); - Visit(nestedTranslationUnit.TranslationUnitDecl); + using var nestedTranslationUnit = TranslationUnit.GetOrCreate(handle); + Visit(nestedTranslationUnit.TranslationUnitDecl); + } + else + { + Visit(translationUnit.TranslationUnitDecl); + } } - else + catch (Exception e) { - Visit(translationUnit.TranslationUnitDecl); + var diagnostic = new Diagnostic(DiagnosticLevel.Error, e.ToString()); + _diagnostics.Add(diagnostic); } } @@ -885,7 +893,7 @@ private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateFunction while (parts.Count != 0) { AppendNamedDecl(part, GetCursorName(part), qualifiedName); - qualifiedName.Append('.'); + qualifiedName.Append("::"); part = parts.Pop(); } @@ -1078,6 +1086,14 @@ private string GetRemappedCursorName(NamedDecl namedDecl) return remappedName; } + name = name.Replace("::", "."); + remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true); + + if (remappedName != name) + { + return remappedName; + } + name = GetCursorQualifiedName(namedDecl, truncateFunctionParameters: true); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true); @@ -1086,6 +1102,14 @@ private string GetRemappedCursorName(NamedDecl namedDecl) return remappedName; } + name = name.Replace("::", "."); + remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true); + + if (remappedName != name) + { + return remappedName; + } + name = GetCursorName(namedDecl); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true); @@ -1188,11 +1212,34 @@ private string GetRemappedTypeName(Cursor cursor, Cursor context, Type type, out name = "_"; name += GetRemappedCursorName(matchingField); } - else if (parentRecordDecl.AnonymousRecords.Count > 1) + else { - var index = parentRecordDecl.AnonymousRecords.IndexOf(cursor) + 1; - name += index.ToString(); - } + var index = 0; + + if (parentRecordDecl.AnonymousRecords.Count > 1) + { + index = parentRecordDecl.AnonymousRecords.IndexOf(cursor) + 1; + } + + while ((parentRecordDecl.IsAnonymousStructOrUnion) && (parentRecordDecl.IsUnion == recordType.Decl.IsUnion)) + { + index += 1; + + if (parentRecordDecl.Parent is RecordDecl parentRecordDeclParent) + { + if (parentRecordDeclParent.AnonymousRecords.Count > 0) + { + index += parentRecordDeclParent.AnonymousRecords.Count - 1; + } + parentRecordDecl = parentRecordDeclParent; + } + } + + if (index != 0) + { + name += index.ToString(); + } + } } name += $"_e__{(recordDecl.IsUnion ? "Union" : "Struct")}"; @@ -2193,7 +2240,7 @@ bool IsExcludedByName(Cursor cursor, out bool isExcludedByConflictingDefinition) } } - if (_config.ExcludedNames.Contains(qualifiedName)) + if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(qualifiedName.Replace("::", "."))) { if (_config.LogExclusions) { diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/EnumDeclarationTest.cs index ad90cc98..5004c7f7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/EnumDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/EnumDeclarationTest.cs @@ -122,26 +122,74 @@ public enum MyEnum : {expectedManagedType} public override Task RemapTest() { - var inputContents = @"typedef enum _MyEnum : int + var inputContents = @"typedef enum _MyEnum1 : int { - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, -} MyEnum; + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, +} MyEnum1; + +namespace Namespace1 +{ + namespace Namespace2 + { + typedef enum _MyEnum2 : int + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } MyEnum2; + + typedef enum _MyEnum3 : int + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } MyEnum3; + + typedef enum _MyEnum4 : int + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } MyEnum4; + } +} "; - var expectedOutputContents = $@"namespace ClangSharp.Test -{{ - public enum MyEnum - {{ - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, - }} -}} + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public enum MyEnum1 + { + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, + } + + public enum MyEnum2 + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } + + public enum MyEnum3 + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } + + public enum MyEnum4 + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } +} "; - var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + var remappedNames = new Dictionary { ["_MyEnum1"] = "MyEnum1", ["Namespace1.Namespace2._MyEnum2"] = "MyEnum2", ["_MyEnum3"] = "MyEnum3", ["Namespace1::Namespace2::_MyEnum4"] = "MyEnum4" }; return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs index f74bf6a5..3f17e175 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs @@ -822,6 +822,21 @@ struct MyStruct {nativeType} value; }} w; + struct + {{ + {nativeType} value1; + + struct + {{ + {nativeType} value; + }}; + }}; + + union + {{ + {nativeType} value2; + }}; + MyUnion u; {nativeType} buffer1[4]; MyUnion buffer2[4]; @@ -871,6 +886,39 @@ public ref _Anonymous_e__Struct._w_e__Struct w }} }} + public ref {expectedManagedType} value1 + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous1_e__Struct* pField = &Anonymous.Anonymous1) + {{ + return ref pField->value1; + }} + }} + }} + + public ref {expectedManagedType} value + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous1_e__Struct._Anonymous_e__Struct* pField = &Anonymous.Anonymous1.Anonymous) + {{ + return ref pField->value; + }} + }} + }} + + public ref {expectedManagedType} value2 + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous2_e__Union* pField = &Anonymous.Anonymous2) + {{ + return ref pField->value2; + }} + }} + }} + public ref MyUnion u {{ get @@ -911,6 +959,12 @@ public unsafe partial struct _Anonymous_e__Struct [NativeTypeName(""struct (anonymous struct at ClangUnsavedFile.h:14:9)"")] public _w_e__Struct w; + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:19:9)"")] + public _Anonymous1_e__Struct Anonymous1; + + [NativeTypeName(""MyStruct::(anonymous union at ClangUnsavedFile.h:29:9)"")] + public _Anonymous2_e__Union Anonymous2; + public MyUnion u; [NativeTypeName(""{nativeType} [4]"")] @@ -924,6 +978,26 @@ public partial struct _w_e__Struct public {expectedManagedType} value; }} + public partial struct _Anonymous1_e__Struct + {{ + public {expectedManagedType} value1; + + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:23:13)"")] + public _Anonymous_e__Struct Anonymous; + + public partial struct _Anonymous_e__Struct + {{ + public {expectedManagedType} value; + }} + }} + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous2_e__Union + {{ + [FieldOffset(0)] + public {expectedManagedType} value2; + }} + public partial struct _buffer2_e__FixedBuffer {{ public MyUnion e0; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/EnumDeclarationTest.cs index 03889dae..ce20b520 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/EnumDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/EnumDeclarationTest.cs @@ -122,26 +122,74 @@ public enum MyEnum : {expectedManagedType} public override Task RemapTest() { - var inputContents = @"typedef enum _MyEnum : int + var inputContents = @"typedef enum _MyEnum1 : int { - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, -} MyEnum; + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, +} MyEnum1; + +namespace Namespace1 +{ + namespace Namespace2 + { + typedef enum _MyEnum2 : int + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } MyEnum2; + + typedef enum _MyEnum3 : int + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } MyEnum3; + + typedef enum _MyEnum4 : int + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } MyEnum4; + } +} "; - var expectedOutputContents = $@"namespace ClangSharp.Test -{{ - public enum MyEnum - {{ - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, - }} -}} + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public enum MyEnum1 + { + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, + } + + public enum MyEnum2 + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } + + public enum MyEnum3 + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } + + public enum MyEnum4 + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } +} "; - var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + var remappedNames = new Dictionary { ["_MyEnum1"] = "MyEnum1", ["Namespace1.Namespace2._MyEnum2"] = "MyEnum2", ["_MyEnum3"] = "MyEnum3", ["Namespace1::Namespace2::_MyEnum4"] = "MyEnum4" }; return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs index 4bb258b9..d9790d69 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs @@ -826,6 +826,21 @@ struct MyStruct {nativeType} value; }} w; + struct + {{ + {nativeType} value1; + + struct + {{ + {nativeType} value; + }}; + }}; + + union + {{ + {nativeType} value2; + }}; + MyUnion u; {nativeType} buffer1[4]; MyUnion buffer2[4]; @@ -875,6 +890,39 @@ public ref _Anonymous_e__Struct._w_e__Struct w }} }} + public ref {expectedManagedType} value1 + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous1_e__Struct* pField = &Anonymous.Anonymous1) + {{ + return ref pField->value1; + }} + }} + }} + + public ref {expectedManagedType} value + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous1_e__Struct._Anonymous_e__Struct* pField = &Anonymous.Anonymous1.Anonymous) + {{ + return ref pField->value; + }} + }} + }} + + public ref {expectedManagedType} value2 + {{ + get + {{ + fixed (_Anonymous_e__Struct._Anonymous2_e__Union* pField = &Anonymous.Anonymous2) + {{ + return ref pField->value2; + }} + }} + }} + public ref MyUnion u {{ get @@ -915,6 +963,12 @@ public unsafe partial struct _Anonymous_e__Struct [NativeTypeName(""struct (anonymous struct at ClangUnsavedFile.h:14:9)"")] public _w_e__Struct w; + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:19:9)"")] + public _Anonymous1_e__Struct Anonymous1; + + [NativeTypeName(""MyStruct::(anonymous union at ClangUnsavedFile.h:29:9)"")] + public _Anonymous2_e__Union Anonymous2; + public MyUnion u; [NativeTypeName(""{nativeType} [4]"")] @@ -928,6 +982,26 @@ public partial struct _w_e__Struct public {expectedManagedType} value; }} + public partial struct _Anonymous1_e__Struct + {{ + public {expectedManagedType} value1; + + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:23:13)"")] + public _Anonymous_e__Struct Anonymous; + + public partial struct _Anonymous_e__Struct + {{ + public {expectedManagedType} value; + }} + }} + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous2_e__Union + {{ + [FieldOffset(0)] + public {expectedManagedType} value2; + }} + public partial struct _buffer2_e__FixedBuffer {{ public MyUnion e0; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/EnumDeclarationTest.cs index 7c202793..15e9bc00 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/EnumDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/EnumDeclarationTest.cs @@ -122,26 +122,74 @@ public enum MyEnum : {expectedManagedType} public override Task RemapTest() { - var inputContents = @"typedef enum _MyEnum : int + var inputContents = @"typedef enum _MyEnum1 : int { - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, -} MyEnum; + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, +} MyEnum1; + +namespace Namespace1 +{ + namespace Namespace2 + { + typedef enum _MyEnum2 : int + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } MyEnum2; + + typedef enum _MyEnum3 : int + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } MyEnum3; + + typedef enum _MyEnum4 : int + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } MyEnum4; + } +} "; - var expectedOutputContents = $@"namespace ClangSharp.Test -{{ - public enum MyEnum - {{ - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, - }} -}} + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public enum MyEnum1 + { + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, + } + + public enum MyEnum2 + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } + + public enum MyEnum3 + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } + + public enum MyEnum4 + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } +} "; - var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + var remappedNames = new Dictionary { ["_MyEnum1"] = "MyEnum1", ["Namespace1.Namespace2._MyEnum2"] = "MyEnum2", ["_MyEnum3"] = "MyEnum3", ["Namespace1::Namespace2::_MyEnum4"] = "MyEnum4" }; return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs index 8920de91..3e7cc7dd 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs @@ -830,6 +830,21 @@ struct MyStruct {nativeType} value; }} w; + struct + {{ + {nativeType} value1; + + struct + {{ + {nativeType} value; + }}; + }}; + + union + {{ + {nativeType} value2; + }}; + MyUnion u; {nativeType} buffer1[4]; MyUnion buffer2[4]; @@ -874,6 +889,30 @@ public ref _Anonymous_e__Struct._w_e__Struct w }} }} + public ref {expectedManagedType} value1 + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous1.value1, 1)); + }} + }} + + public ref {expectedManagedType} value + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous1.Anonymous.value, 1)); + }} + }} + + public ref {expectedManagedType} value2 + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous2.value2, 1)); + }} + }} + public ref MyUnion u {{ get @@ -905,6 +944,12 @@ public unsafe partial struct _Anonymous_e__Struct [NativeTypeName(""struct (anonymous struct at ClangUnsavedFile.h:14:9)"")] public _w_e__Struct w; + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:19:9)"")] + public _Anonymous1_e__Struct Anonymous1; + + [NativeTypeName(""MyStruct::(anonymous union at ClangUnsavedFile.h:29:9)"")] + public _Anonymous2_e__Union Anonymous2; + public MyUnion u; [NativeTypeName(""{nativeType} [4]"")] @@ -918,6 +963,26 @@ public partial struct _w_e__Struct public {expectedManagedType} value; }} + public partial struct _Anonymous1_e__Struct + {{ + public {expectedManagedType} value1; + + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:23:13)"")] + public _Anonymous_e__Struct Anonymous; + + public partial struct _Anonymous_e__Struct + {{ + public {expectedManagedType} value; + }} + }} + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous2_e__Union + {{ + [FieldOffset(0)] + public {expectedManagedType} value2; + }} + public partial struct _buffer2_e__FixedBuffer {{ public MyUnion e0; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/EnumDeclarationTest.cs index b3ac1e1e..b86e9f38 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/EnumDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/EnumDeclarationTest.cs @@ -122,26 +122,74 @@ public enum MyEnum : {expectedManagedType} public override Task RemapTest() { - var inputContents = @"typedef enum _MyEnum : int + var inputContents = @"typedef enum _MyEnum1 : int { - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, -} MyEnum; + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, +} MyEnum1; + +namespace Namespace1 +{ + namespace Namespace2 + { + typedef enum _MyEnum2 : int + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } MyEnum2; + + typedef enum _MyEnum3 : int + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } MyEnum3; + + typedef enum _MyEnum4 : int + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } MyEnum4; + } +} "; - var expectedOutputContents = $@"namespace ClangSharp.Test -{{ - public enum MyEnum - {{ - MyEnum_Value1, - MyEnum_Value2, - MyEnum_Value3, - }} -}} + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public enum MyEnum1 + { + MyEnum1_Value1, + MyEnum1_Value2, + MyEnum1_Value3, + } + + public enum MyEnum2 + { + MyEnum2_Value1, + MyEnum2_Value2, + MyEnum2_Value3, + } + + public enum MyEnum3 + { + MyEnum3_Value1, + MyEnum3_Value2, + MyEnum3_Value3, + } + + public enum MyEnum4 + { + MyEnum4_Value1, + MyEnum4_Value2, + MyEnum4_Value3, + } +} "; - var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + var remappedNames = new Dictionary { ["_MyEnum1"] = "MyEnum1", ["Namespace1.Namespace2._MyEnum2"] = "MyEnum2", ["_MyEnum3"] = "MyEnum3", ["Namespace1::Namespace2::_MyEnum4"] = "MyEnum4" }; return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs index 218d24d0..ee864cfd 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs @@ -834,6 +834,21 @@ struct MyStruct {nativeType} value; }} w; + struct + {{ + {nativeType} value1; + + struct + {{ + {nativeType} value; + }}; + }}; + + union + {{ + {nativeType} value2; + }}; + MyUnion u; {nativeType} buffer1[4]; MyUnion buffer2[4]; @@ -878,6 +893,30 @@ public ref _Anonymous_e__Struct._w_e__Struct w }} }} + public ref {expectedManagedType} value1 + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous1.value1, 1)); + }} + }} + + public ref {expectedManagedType} value + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous1.Anonymous.value, 1)); + }} + }} + + public ref {expectedManagedType} value2 + {{ + get + {{ + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous2.value2, 1)); + }} + }} + public ref MyUnion u {{ get @@ -909,6 +948,12 @@ public unsafe partial struct _Anonymous_e__Struct [NativeTypeName(""struct (anonymous struct at ClangUnsavedFile.h:14:9)"")] public _w_e__Struct w; + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:19:9)"")] + public _Anonymous1_e__Struct Anonymous1; + + [NativeTypeName(""MyStruct::(anonymous union at ClangUnsavedFile.h:29:9)"")] + public _Anonymous2_e__Union Anonymous2; + public MyUnion u; [NativeTypeName(""{nativeType} [4]"")] @@ -922,6 +967,26 @@ public partial struct _w_e__Struct public {expectedManagedType} value; }} + public partial struct _Anonymous1_e__Struct + {{ + public {expectedManagedType} value1; + + [NativeTypeName(""MyStruct::(anonymous struct at ClangUnsavedFile.h:23:13)"")] + public _Anonymous_e__Struct Anonymous; + + public partial struct _Anonymous_e__Struct + {{ + public {expectedManagedType} value; + }} + }} + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous2_e__Union + {{ + [FieldOffset(0)] + public {expectedManagedType} value2; + }} + public partial struct _buffer2_e__FixedBuffer {{ public MyUnion e0;