Skip to content

Commit

Permalink
Nested records
Browse files Browse the repository at this point in the history
  • Loading branch information
lithiumtoast committed Jan 6, 2025
1 parent 3c84e55 commit 45dc58e
Show file tree
Hide file tree
Showing 27 changed files with 282 additions and 198 deletions.
6 changes: 6 additions & 0 deletions src/cs/production/c2ffi.Data/Nodes/CRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public class CRecord : CNodeWithLocation
[JsonPropertyName("fields")]
public ImmutableArray<CRecordField> Fields { get; set; } = ImmutableArray<CRecordField>.Empty;

/// <summary>
/// Gets or sets the nested records.
/// </summary>
[JsonPropertyName("nested")]
public ImmutableArray<CRecord> NestedRecords { get; set; } = ImmutableArray<CRecord>.Empty;

/// <inheritdoc />
[ExcludeFromCodeCoverage]
public override string ToString()
Expand Down
175 changes: 119 additions & 56 deletions src/cs/production/c2ffi.Tool/Extract/Explore/ExploreContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using bottlenoselabs;
using c2ffi.Clang;
using c2ffi.Data;
using c2ffi.Data.Nodes;
using c2ffi.Extract.Parse;
using Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -38,10 +39,14 @@ public void TryEnqueueNode(NodeInfo info)
_frontier.EnqueueNode(info);
}

public void TryExplore(NodeInfo info)
public CNode? Explore(NodeInfo info)
{
var handler = GetHandler(info.NodeKind);
var node = handler.ExploreInternal(this, info);
return handler.ExploreInternal(this, info);
}

public void AddNode(CNode? node)
{
if (node != null)
{
_ffiBuilder.AddNode(node);
Expand Down Expand Up @@ -79,33 +84,86 @@ public CType VisitType(
return string.IsNullOrEmpty(commentString) ? null : commentString;
}

public NodeInfo CreateTopLevelNodeInfo(
CNodeKind nodeKind,
clang.CXCursor clangCursor)
public NodeInfo CreateNodeInfoFunction(clang.CXCursor clangCursor)
{
var clangCursorName = clangCursor.Spelling();
var clangCursorType = clang.clang_getCursorType(clangCursor);
var clangTypeInfo = ClangTypeInfoProvider.GetTypeInfo(clangCursorType);

if (nodeKind == CNodeKind.MacroObject)
{
return CreateNodeInfo(
nodeKind,
clangCursorName,
clangCursorType.Spelling(),
clangCursor,
clangCursorType,
null);
}
var nodeInfo = CreateNodeInfo(
CNodeKind.Function,
clangCursorName,
clangTypeInfo.Name,
clangCursor,
clangTypeInfo.ClangType,
null);
return nodeInfo;
}

public NodeInfo CreateNodeInfoMacroObject(clang.CXCursor clangCursor)
{
var clangCursorName = clangCursor.Spelling();
var clangCursorType = clang.clang_getCursorType(clangCursor);

var nodeInfo = CreateNodeInfo(
CNodeKind.MacroObject,
clangCursorName,
clangCursorType.Spelling(),
clangCursor,
clangCursorType,
null);
return nodeInfo;
}

public NodeInfo CreateNodeInfoVariable(clang.CXCursor clangCursor)
{
var clangCursorName = clangCursor.Spelling();
var clangCursorType = clang.clang_getCursorType(clangCursor);
var clangTypeInfo = ClangTypeInfoProvider.GetTypeInfo(clangCursorType);

return CreateNodeInfo(
var nodeInfo = CreateNodeInfo(
CNodeKind.Variable,
clangCursorName,
clangTypeInfo.Name,
clangCursor,
clangTypeInfo.ClangType,
null);
return nodeInfo;
}

public NodeInfo CreateNodeInfoExplicitlyIncluded(CNodeKind nodeKind, clang.CXCursor clangCursor)
{
var clangCursorName = clangCursor.Spelling();
var clangCursorType = clang.clang_getCursorType(clangCursor);
var clangTypeInfo = ClangTypeInfoProvider.GetTypeInfo(clangCursorType);

var nodeInfo = CreateNodeInfo(
nodeKind,
clangCursorName,
clangTypeInfo.Name,
clangCursor,
clangTypeInfo.ClangType,
null);
return nodeInfo;
}

public NodeInfo CreateNodeInfoRecordNested(
CNodeKind nodeKind,
string typeName,
clang.CXCursor clangCursor,
clang.CXType clangType,
NodeInfo parentInfo)
{
var clangCursorName = clangCursor.Spelling();

var nodeInfo = CreateNodeInfo(
nodeKind,
clangCursorName,
typeName,
clangCursor,
clangType,
parentInfo);
return nodeInfo;
}

public void Dispose()
Expand All @@ -131,13 +189,41 @@ public string GetFieldName(clang.CXCursor clangCursor)
return name;
}

private NodeInfo CreateNodeInfo(
CNodeKind kind,
string name,
string typeName,
clang.CXCursor clangCursor,
clang.CXType clangType,
NodeInfo? parentInfo)
{
var location = ParseContext.Location(clangCursor, out _);
var sizeOf = ParseContext.SizeOf(kind, clangType);
var alignOf = ParseContext.AlignOf(kind, clangType);

var result = new NodeInfo
{
NodeKind = kind,
Name = name,
TypeName = typeName,
ClangType = clangType,
ClangCursor = clangCursor,
Location = location,
Parent = parentInfo,
SizeOf = sizeOf,
AlignOf = alignOf
};

return result;
}

private CType VisitTypeInternal(
CNodeKind nodeKind,
string typeName,
clang.CXType clangType,
clang.CXType clangContainerType,
clang.CXCursor clangCursor,
NodeInfo? rootNode)
NodeInfo? parentInfo)
{
var clangCursorLocation = clang.clang_getTypeDeclaration(clangType);
var location = ParseContext.Location(clangCursorLocation, out _);
Expand All @@ -150,17 +236,17 @@ private CType VisitTypeInternal(
#pragma warning restore IDE0010
{
case CNodeKind.Pointer:
innerType = VisitTypeInternalPointer(nodeKind, clangType, rootNode);
innerType = VisitTypeInternalPointer(nodeKind, clangType, parentInfo);
sizeOf = ParseContext.PointerSize;
alignOf = ParseContext.PointerSize;
break;
case CNodeKind.Array:
innerType = VisitTypeInternalArray(nodeKind, clangType, rootNode);
innerType = VisitTypeInternalArray(nodeKind, clangType, parentInfo);
sizeOf = ParseContext.PointerSize;
alignOf = ParseContext.PointerSize;
break;
case CNodeKind.TypeAlias:
innerType = VisitTypeInternalTypeAlias(nodeKind, clangCursor, rootNode);
innerType = VisitTypeInternalTypeAlias(nodeKind, clangCursor, parentInfo);
sizeOf = innerType.SizeOf;
alignOf = innerType.AlignOf;
break;
Expand Down Expand Up @@ -208,20 +294,25 @@ private CType VisitTypeInternal(
return type;
}

if (location.IsSystem && nodeKind != CNodeKind.FunctionPointer)
if (nodeKind is CNodeKind.Union or CNodeKind.Struct && isAnonymous)
{
return type;
}

var info = CreateNodeInfo(type.NodeKind, type.Name, type.Name, clangCursor, clangType, rootNode);
if (nodeKind != CNodeKind.FunctionPointer && location.IsSystem)
{
return type;
}

var info = CreateNodeInfo(type.NodeKind, type.Name, type.Name, clangCursor, clangType, parentInfo);
TryEnqueueNode(info);
return type;
}

private CType VisitTypeInternalPointer(
CNodeKind nodeKind,
clang.CXType clangType,
NodeInfo? rootNode)
NodeInfo? parentInfo)
{
var pointeeTypeCandidate = clang.clang_getPointeeType(clangType);
var pointeeTypeInfo = ClangTypeInfoProvider.GetTypeInfo(pointeeTypeCandidate, nodeKind);
Expand All @@ -232,14 +323,14 @@ private CType VisitTypeInternalPointer(
pointeeTypeInfo.ClangType,
pointeeTypeCandidate,
pointeeTypeInfo.ClangCursor,
rootNode);
parentInfo);
return innerType;
}

private CType VisitTypeInternalArray(
CNodeKind nodeKind,
clang.CXType clangType,
NodeInfo? rootNode)
NodeInfo? parentInfo)
{
var elementTypeCandidate = clang.clang_getArrayElementType(clangType);
var elementTypeInfo = ClangTypeInfoProvider.GetTypeInfo(elementTypeCandidate, nodeKind);
Expand All @@ -250,14 +341,14 @@ private CType VisitTypeInternalArray(
elementTypeInfo.ClangType,
elementTypeCandidate,
elementTypeInfo.ClangCursor,
rootNode);
parentInfo);
return innerType;
}

private CType VisitTypeInternalTypeAlias(
CNodeKind nodeKind,
clang.CXCursor clangCursor,
NodeInfo? rootNode)
NodeInfo? parentInfo)
{
var aliasTypeCandidate = clang.clang_getTypedefDeclUnderlyingType(clangCursor);
var aliasTypeInfo = ClangTypeInfoProvider.GetTypeInfo(aliasTypeCandidate, nodeKind);
Expand All @@ -268,39 +359,11 @@ private CType VisitTypeInternalTypeAlias(
aliasTypeInfo.ClangType,
aliasTypeCandidate,
aliasTypeInfo.ClangCursor,
rootNode);
parentInfo);

return innerType;
}

private NodeInfo CreateNodeInfo(
CNodeKind kind,
string name,
string typeName,
clang.CXCursor clangCursor,
clang.CXType clangType,
NodeInfo? parentInfo)
{
var location = ParseContext.Location(clangCursor, out _);
var sizeOf = ParseContext.SizeOf(kind, clangType);
var alignOf = ParseContext.AlignOf(kind, clangType);

var result = new NodeInfo
{
NodeKind = kind,
Name = name,
TypeName = typeName,
ClangType = clangType,
ClangCursor = clangCursor,
Location = location,
Parent = parentInfo,
SizeOf = sizeOf,
AlignOf = alignOf
};

return result;
}

private static ImmutableDictionary<CNodeKind, NodeExplorer> GetNodeHandlers(IServiceProvider services)
{
var result = new Dictionary<CNodeKind, NodeExplorer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ private void Explore(ExploreContext exploreContext, ArrayDeque<NodeInfo> frontie
{
while (frontier.Count > 0)
{
var node = frontier.PopFront()!;
exploreContext.TryExplore(node);
var nodeInfo = frontier.PopFront()!;
var node = exploreContext.Explore(nodeInfo);
exploreContext.AddNode(node);
}
}

Expand Down
Loading

0 comments on commit 45dc58e

Please sign in to comment.