Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,20 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type
{
result.typeName = result.typeName.Split(s_doubleColonSeparator, StringSplitOptions.RemoveEmptyEntries).Last();
result.typeName = GetRemappedName(result.typeName, cursor, tryRemapOperatorName: false, out _, skipUsing: true);

// A nested type needs to be qualified by its containing type(s) so it resolves
// when referenced from another scope (e.g. `A::Inner` -> `A.Inner`). Namespaces
// are flattened away, so only walk the enclosing record decls.

var qualificationBuilder = new StringBuilder();

for (var declContext = tagType.Decl.DeclContext; declContext is RecordDecl parentRecordDecl; declContext = parentRecordDecl.DeclContext)
{
var parentRecordDeclName = GetRemappedCursorName(parentRecordDecl, out _, skipUsing: true);
_ = qualificationBuilder.Insert(0, '.').Insert(0, EscapeName(parentRecordDeclName));
}

result.typeName = qualificationBuilder.Append(result.typeName).ToString();
}
}
else if (type is TemplateSpecializationType templateSpecializationType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System.Threading.Tasks;
using NUnit.Framework;

namespace ClangSharp.UnitTests;

/// <summary>
/// Regression test for https://github.com/dotnet/ClangSharp/issues/579.
/// A nested type referenced from another scope must be qualified by its containing type(s)
/// (e.g. <c>A::Inner</c> -&gt; <c>A.Inner</c>) so it resolves in the generated C#.
/// </summary>
[Platform("win")]
public sealed class NestedTypeReferenceTest : PInvokeGeneratorTest
{
[Test]
public Task NestedTypeIsQualified()
{
var inputContents = @"struct A
{
struct Inner
{
int value;
};
};

struct B
{
A::Inner inner;
};
";

var expectedOutputContents = @"namespace ClangSharp.Test
{
public partial struct A
{

public partial struct Inner
{
public int value;
}
}

public partial struct B
{
[NativeTypeName(""A::Inner"")]
public A.Inner inner;
}
}
";

return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
}
}
Loading