Skip to content

Commit

Permalink
Merge pull request #442 from tannergooding/sml-fix
Browse files Browse the repository at this point in the history
Add a generate-native-bitfield-attribute switch
  • Loading branch information
tannergooding authored Apr 9, 2023
2 parents a55dc86 + 8d8b998 commit d9e38ec
Show file tree
Hide file tree
Showing 23 changed files with 3,538 additions and 68 deletions.
21 changes: 21 additions & 0 deletions sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldDesc.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.Collections.Generic;

namespace ClangSharp.Abstractions;

public struct BitfieldDesc
{
public Type TypeBacking { get; set; }

public List<BitfieldRegion> Regions { get; set; }
}

public struct BitfieldRegion
{
public string Name { get; set; }

public long Offset { get; set; }

public long Length { get; set; }
}
33 changes: 27 additions & 6 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1753,8 +1753,8 @@ private void VisitRecordDecl(RecordDecl recordDecl)
_testOutputBuilder.WriteBlockEnd();
}

var bitfieldTypes = GetBitfieldCount(recordDecl);
var bitfieldIndex = (bitfieldTypes.Length == 1) ? -1 : 0;
var bitfieldDescs = GetBitfieldDescs(recordDecl);
var bitfieldIndex = (bitfieldDescs.Length == 1) ? -1 : 0;

var bitfieldPreviousSize = 0L;
var bitfieldRemainingBits = 0L;
Expand All @@ -1763,7 +1763,7 @@ private void VisitRecordDecl(RecordDecl recordDecl)
{
if (fieldDecl.IsBitField)
{
VisitBitfieldDecl(fieldDecl, bitfieldTypes, recordDecl, contextName: "", ref bitfieldIndex, ref bitfieldPreviousSize, ref bitfieldRemainingBits);
VisitBitfieldDecl(fieldDecl, bitfieldDescs, recordDecl, contextName: "", ref bitfieldIndex, ref bitfieldPreviousSize, ref bitfieldRemainingBits);
}
else
{
Expand Down Expand Up @@ -2351,7 +2351,7 @@ void OutputVtblHelperMethods(CXXRecordDecl rootCxxRecordDecl, CXXRecordDecl cxxR
}
}

void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl, string contextName, ref int index, ref long previousSize, ref long remainingBits)
void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, RecordDecl recordDecl, string contextName, ref int index, ref long previousSize, ref long remainingBits)
{
Debug.Assert(fieldDecl.IsBitField);

Expand Down Expand Up @@ -2384,7 +2384,8 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl,
remainingBits = currentSize * 8;
previousSize = 0;

typeBacking = (index > 0) ? types[index - 1] : types[0];
var bitfieldDesc = (index > 0) ? bitfieldDescs[index - 1] : bitfieldDescs[0];
typeBacking = bitfieldDesc.TypeBacking;
typeNameBacking = GetRemappedTypeName(fieldDecl, context: null, typeBacking, out _);

if (parent == recordDecl)
Expand All @@ -2396,6 +2397,26 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl,
Offset = parent.IsUnion ? 0 : null,
NeedsNewKeyword = false,
Location = fieldDecl.Location,
WriteCustomAttrs = static context => {
(var bitfieldDesc, var generator) = ((BitfieldDesc, PInvokeGenerator))context;

if (!generator.Config.GenerateNativeBitfieldAttribute)
{
return;
}

var outputBuilder = generator._outputBuilder;
Debug.Assert(outputBuilder is not null);

foreach (var bitfieldRegion in bitfieldDesc.Regions)
{
outputBuilder.WriteCustomAttribute($"NativeBitfield(\"{bitfieldRegion.Name}\", offset: {bitfieldRegion.Offset}, length: {bitfieldRegion.Length})");
}

var namespaceName = generator.GetNamespace("NativeBitfieldAttribute");
generator.AddUsingDirective(outputBuilder, namespaceName);
},
CustomAttrGeneratorData = (bitfieldDesc, this),
};
_outputBuilder.BeginField(in fieldDesc);
_outputBuilder.WriteRegularField(typeNameBacking, bitfieldName);
Expand All @@ -2416,7 +2437,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, Type[] types, RecordDecl recordDecl,
bitfieldName += index.ToString();
}

typeBacking = (index > 0) ? types[index - 1] : types[0];
typeBacking = (index > 0) ? bitfieldDescs[index - 1].TypeBacking : bitfieldDescs[0].TypeBacking;
typeNameBacking = GetRemappedTypeName(fieldDecl, context: null, typeBacking, out _);
}

Expand Down
Loading

0 comments on commit d9e38ec

Please sign in to comment.