Skip to content

Commit

Permalink
FIx macro object type infos (#21)
Browse files Browse the repository at this point in the history
* FIx macro object type infos

* Add tests

* Fix tests
  • Loading branch information
lithiumtoast authored Apr 4, 2024
1 parent 1aed7a7 commit 5b396f1
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 101 deletions.
24 changes: 24 additions & 0 deletions src/c/tests/macro_objects/macro_object_uint64/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"inputFilePath": "./main.c",
"userIncludeDirectories": [
"../../../production/ffi_helper/include"
],
"ignoredIncludeFiles": [
"../../../production/ffi_helper/include/ffi_helper.h"
],
"targetPlatforms": {
"windows": {
"x86_64-pc-windows-msvc": {},
"aarch64-pc-windows-msvc": {}
},
"macos": {
"aarch64-apple-darwin": {},
"x86_64-apple-darwin": {},
"aarch64-apple-ios": {}
},
"linux": {
"x86_64-unknown-linux-gnu": {},
"aarch64-unknown-linux-gnu": {}
}
}
}
5 changes: 5 additions & 0 deletions src/c/tests/macro_objects/macro_object_uint64/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stdio.h>
#include <stdint.h>
#include "ffi_helper.h"

#define MACRO_OBJECT_UINT64 ((uint64_t)42)
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public bool IsIncludeIgnored(string filePath)

public CTypeInfo VisitType(
clang.CXType clangType,
ExploreNodeInfo parentInfo,
ExploreNodeInfo? parentInfo,
CNodeKind? nodeKind = null)
{
var clangTypeInfo = ClangTypeInfoProvider.GetTypeInfo(clangType, parentInfo.NodeKind);
var clangTypeInfo = ClangTypeInfoProvider.GetTypeInfo(clangType, parentInfo?.NodeKind);
var nodeKindUsed = nodeKind ?? clangTypeInfo.NodeKind;

var typeInfo = VisitTypeInternal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ protected override bool IsAllowed(ExploreContext context, ExploreNodeInfo info)
CMacroObject? macroObject;
try
{
macroObject = GetMacroObjectFromParsingFile(filePath, context.ParseContext);
macroObject = GetMacroObjectFromParsingFile(filePath, context, info);
}
finally
{
Expand Down Expand Up @@ -111,12 +111,11 @@ int main(void)
return tempFilePath;
}

private CMacroObject? GetMacroObjectFromParsingFile(
string filePath, ParseContext originalParseContext)
private CMacroObject? GetMacroObjectFromParsingFile(string filePath, ExploreContext context, ExploreNodeInfo info)
{
using var parseContext = _clangTranslationUnitParser.ParseTranslationUnit(
filePath,
originalParseContext.ExtractOptions,
context.ParseContext.ExtractOptions,
isCPlusPlus: true,
ignoreWarnings: true,
logClangDiagnostics: false,
Expand Down Expand Up @@ -148,7 +147,6 @@ int main(void)
var declarationStatement =
compoundStatement.GetDescendents(static (cursor, _) =>
cursor.kind == clang.CXCursorKind.CXCursor_DeclStmt).FirstOrDefault();
var readerLineNumber = 0;

var variable = declarationStatement.GetDescendents(static (cursor, _) =>
cursor.kind == clang.CXCursorKind.CXCursor_VarDecl)
Expand All @@ -175,25 +173,13 @@ int main(void)
return null;
}

using var streamReader = new StreamReader(filePath);
var location = MacroLocation(originalParseContext, clangCursor, streamReader, ref readerLineNumber);

var nodeKind = MacroTypeNodeKind(clangType);
var typeName = clangType.Spelling();
var sizeOf = (int)clang.clang_Type_getSizeOf(clangType);
var typeInfo = new CTypeInfo
{
Name = typeName,
NodeKind = nodeKind,
SizeOf = sizeOf
};

var typeInfo = context.VisitType(clangType, info);
var macroObject = new CMacroObject
{
Name = macroName,
Value = value,
TypeInfo = typeInfo,
Location = location
Location = info.Location
};

return macroObject;
Expand Down Expand Up @@ -249,78 +235,6 @@ int main(void)
return value;
}

private CLocation MacroLocation(
ParseContext parseContext,
clang.CXCursor clangCursor,
StreamReader reader,
ref int readerLineNumber)
{
var location = parseContext.Location(clangCursor);
var locationCommentLineNumber = location.LineNumber - 1;

if (readerLineNumber > locationCommentLineNumber)
{
reader.BaseStream.Seek(0, SeekOrigin.Begin);
readerLineNumber = 0;
}

var line = string.Empty;
while (readerLineNumber != locationCommentLineNumber)
{
line = reader.ReadLine() ?? string.Empty;
readerLineNumber++;
}

var locationString = line.Trim().TrimStart('/').Trim();
var lineIndex = locationString.IndexOf(':', StringComparison.InvariantCulture);
var columnIndex = locationString.IndexOf(':', lineIndex + 1);
var filePathIndex = locationString.IndexOf('(', StringComparison.InvariantCulture);

int columnIndexEnd;
if (filePathIndex == -1)
{
columnIndexEnd = locationString.Length;
}
else
{
columnIndexEnd = filePathIndex - 1;
}

var lineString = locationString[(lineIndex + 1).. columnIndex];
var columnString = locationString[(columnIndex + 1).. columnIndexEnd];
var fileNameString = locationString[..lineIndex];

var filePathString = filePathIndex == -1 ? fileNameString : locationString[(filePathIndex + 1)..^1];
var lineNumber = int.Parse(lineString, CultureInfo.InvariantCulture);
var lineColumn = int.Parse(columnString, CultureInfo.InvariantCulture);

var actualLocation = new CLocation
{
FileName = fileNameString,
FilePath = filePathString,
LineNumber = lineNumber,
LineColumn = lineColumn
};
return actualLocation;
}

private static CNodeKind MacroTypeNodeKind(clang.CXType type)
{
if (type.IsPrimitive())
{
return CNodeKind.Primitive;
}

return type.kind switch
{
clang.CXTypeKind.CXType_Typedef => CNodeKind.TypeAlias,
clang.CXTypeKind.CXType_Enum => CNodeKind.Enum,
clang.CXTypeKind.CXType_Pointer => CNodeKind.Pointer,
clang.CXTypeKind.CXType_ConstantArray => CNodeKind.Array,
_ => CNodeKind.Unknown
};
}

private sealed class MacroObjectCandidate
{
public string Name { get; init; } = string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ private void FfiMacroObjectExists(CTestFfiTargetPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("int");
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("int");
macroObject.Type.InnerType.Should().BeNull();
}

private void FfiMacroObjectDoesNotExist(CTestFfiTargetPlatform ffi)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ private void FfiMacroObjectExists(CTestFfiTargetPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("int");
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("int");
macroObject.Type.InnerType.Should().BeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ private void FfiMacroObjectExists(CTestFfiTargetPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("const char *");
macroObject.Value.Should().Be("\"42\"");
macroObject.Type.Name.Should().Be("const char *");
macroObject.Type.InnerType.Should().NotBeNull();
macroObject.Type.InnerType!.Name.Should().Be("const char");
macroObject.Type.InnerType!.InnerType.Should().BeNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved.
// Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.

using c2ffi.Tests.Library.Models;
using FluentAssertions;

#pragma warning disable CA1308
#pragma warning disable CA1707

namespace c2ffi.Tests.EndToEnd.Extract.MacroObjects.macro_object_uint64;

public class Test : ExtractFfiTest
{
private const string MacroObjectName = "MACRO_OBJECT_UINT64";

[Fact]
public void MacroObject()
{
var ffis = GetTargetPlatformFfis(
$"src/c/tests/macro_objects/{MacroObjectName.ToLowerInvariant()}/config.json");
Assert.True(ffis.Length > 0);

foreach (var ffi in ffis)
{
FfiMacroObjectExists(ffi);
}
}

private void FfiMacroObjectExists(CTestFfiTargetPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("uint64_t");
macroObject.Type.InnerType.Should().NotBeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ private void FfiMacroObjectExists(CTestFfiCrossPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("int");
macroObject.Name.Should().Be(MacroObjectName);
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("int");
macroObject.Type.InnerType.Should().BeNull();
}

private void FfiMacroObjectDoesNotExist(CTestFfiCrossPlatform ffi)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ private void FfiMacroObjectExists(CTestFfiCrossPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("int");
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("int");
macroObject.Type.InnerType.Should().BeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ private void FfiMacroObjectExists(CTestFfiCrossPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.TypeName.Should().Be("const char *");
macroObject.Value.Should().Be("\"42\"");
macroObject.Type.Name.Should().Be("const char *");
macroObject.Type.InnerType.Should().NotBeNull();
macroObject.Type.InnerType!.Name.Should().Be("const char");
macroObject.Type.InnerType!.InnerType.Should().BeNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved.
// Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.

using c2ffi.Tests.Library.Models;
using FluentAssertions;
using Xunit;

#pragma warning disable CA1308
#pragma warning disable CA1707

namespace c2ffi.Tests.EndToEnd.Merge.MacroObjects.macro_object_uint64;

public class Test : MergeFfisTest
{
private const string MacroObjectName = "MACRO_OBJECT_UINT64";

[Fact]
public void MacroObject()
{
var ffi = GetCrossPlatformFfi(
$"src/c/tests/macro_objects/{MacroObjectName.ToLowerInvariant()}/ffi");
FfiMacroObjectExists(ffi);
}

private void FfiMacroObjectExists(CTestFfiCrossPlatform ffi)
{
var macroObject = ffi.GetMacroObject(MacroObjectName);
macroObject.Name.Should().Be(MacroObjectName);
macroObject.Value.Should().Be("42");
macroObject.Type.Name.Should().Be("uint64_t");
macroObject.Type.InnerType.Should().NotBeNull();
}
}
4 changes: 2 additions & 2 deletions src/cs/tests/c2ffi.Tests.Library/Models/CTestMacroObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ public class CTestMacroObject
{
public string Name { get; }

public string TypeName { get; }
public CTestTypeInfo Type { get; }

public string Value { get; }

public CTestMacroObject(CMacroObject macroObject)
{
Name = macroObject.Name;
TypeName = macroObject.TypeInfo.Name;
Type = new CTestTypeInfo(macroObject.TypeInfo);
Value = macroObject.Value;
}
}

0 comments on commit 5b396f1

Please sign in to comment.