add bindings
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
FileVersion = 1
|
||||
|
||||
[Project]
|
||||
Name = "SpirVCross.Setup"
|
||||
StartupObject = "SpirVCross.Setup.Program"
|
||||
|
||||
[Dependencies]
|
||||
corlib = "*"
|
||||
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
|
||||
@@ -0,0 +1,9 @@
|
||||
FileVersion = 1
|
||||
ExtraPlatforms = ["Linux32", "Linux64", "macOS"]
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "SpirVCross.Setup"
|
||||
|
||||
[Projects]
|
||||
"SpirVCross.Setup" = {Path = "."}
|
||||
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
|
||||
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Cpp2Beef;
|
||||
using LibClang;
|
||||
|
||||
namespace SpirVCross.Setup;
|
||||
|
||||
class SpriVCrossGenerator : Cpp2BeefGenerator, this(Span<char8*> args)
|
||||
{
|
||||
protected override Span<char8*> Args => args;
|
||||
protected override Flags Flags => .None;
|
||||
|
||||
StreamWriter spvWriter = new .()..Create("../src/SpirV.bf")..Write("""
|
||||
// This file was generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
|
||||
namespace SpirVCross;
|
||||
|
||||
|
||||
""") ~ delete _;
|
||||
StreamWriter spvcWriter = new .()..Create("../src/SpirVCross.bf")..Write("""
|
||||
// This file was generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
|
||||
namespace SpirVCross;
|
||||
|
||||
|
||||
""") ~ delete _;
|
||||
|
||||
protected override StreamWriter GetWriterForHeader(StringView header)
|
||||
{
|
||||
// Here you define the target file to which a cursor should be written
|
||||
// Returning null skips the cursor
|
||||
if (header.EndsWith("spirv_cross_c.h"))
|
||||
return spvcWriter;
|
||||
if (header.EndsWith("spirv.h"))
|
||||
return spvWriter;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override bool IsOutParam(CXCursor arg, CXCursor method)
|
||||
{
|
||||
let type = Clang.GetCursorType(arg);
|
||||
if (type.kind != .Pointer) return false;
|
||||
let spelling = GetTypeSpelling!(Clang.GetPointeeType(type));
|
||||
return handles.ContainsAlt(spelling);
|
||||
}
|
||||
|
||||
HashSet<String> handles = new .(16) ~ DeleteContainerAndItems!(_);
|
||||
|
||||
protected override void HandleCursor(CXCursor cursor)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .TypedefDecl:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling == "spvc_bool")
|
||||
return;
|
||||
|
||||
if (spelling.EndsWith("_flags"))
|
||||
{
|
||||
BeginCursor(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("typealias ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(" = ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Length--;
|
||||
str.Append("Bits;");
|
||||
return;
|
||||
}
|
||||
|
||||
let type = Clang.GetTypedefDeclUnderlyingType(cursor);
|
||||
let typeSpelling = GetTypeSpelling!(type);
|
||||
if (!(typeSpelling.StartsWith("struct spvc_") || typeSpelling.StartsWith("const struct spvc_")) || !typeSpelling.EndsWith("_s *"))
|
||||
break;
|
||||
BeginCursor(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("struct ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(" : int {}");
|
||||
handles.Add(new .(spelling));
|
||||
return;
|
||||
case .StructDecl:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling.EndsWith("_s"))
|
||||
return;
|
||||
default:
|
||||
}
|
||||
base.HandleCursor(cursor);
|
||||
}
|
||||
|
||||
protected override void GetNameInBindings(CXCursor cursor, String outString)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .EnumDecl:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling.StartsWith("Spv") && spelling.EndsWith('_'))
|
||||
{
|
||||
outString.Append(spelling[..<^1]);
|
||||
return;
|
||||
}
|
||||
fallthrough;
|
||||
case .StructDecl, .UnionDecl, .TypedefDecl:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (!spelling.StartsWith("spvc_"))
|
||||
break;
|
||||
UpperSnakeCase2PascalCase(spelling, outString);
|
||||
return;
|
||||
case .EnumConstantDecl:
|
||||
var parentSpelling = GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor));
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
if (parentSpelling.StartsWith("spvc_"))
|
||||
{
|
||||
bool bit = false;
|
||||
if (parentSpelling.EndsWith("_flag_bits"))
|
||||
{
|
||||
parentSpelling.RemoveFromEnd("_flag_bits".Length);
|
||||
bit = true;
|
||||
}
|
||||
if (spelling.EndsWith("_INT_MAX") || spelling.EndsWith("_MAX_INT"))
|
||||
outString.Append("//");
|
||||
if (spelling.StartsWith(parentSpelling, .OrdinalIgnoreCase))
|
||||
spelling.RemoveFromStart(parentSpelling.Length);
|
||||
else
|
||||
break;
|
||||
if (bit && spelling.EndsWith("_BIT"))
|
||||
spelling.RemoveFromEnd(4);
|
||||
if (spelling[0] == '_' && spelling[1].IsDigit)
|
||||
outString.Append('_');
|
||||
UpperSnakeCase2PascalCase(spelling, outString);
|
||||
}
|
||||
else if (parentSpelling.StartsWith("Spv"))
|
||||
{
|
||||
if (parentSpelling == "SpvOp_")
|
||||
parentSpelling = "Spv";
|
||||
if (parentSpelling.EndsWith('_'))
|
||||
parentSpelling.RemoveFromEnd(1);
|
||||
StringView suffix = null;
|
||||
if (parentSpelling.EndsWith("Shift"))
|
||||
suffix = "Shift";
|
||||
else if (parentSpelling.EndsWith("Mask"))
|
||||
suffix = "Mask";
|
||||
parentSpelling.RemoveFromEnd(suffix.Length);
|
||||
|
||||
if (spelling.StartsWith(parentSpelling))
|
||||
spelling.RemoveFromStart(parentSpelling.Length);
|
||||
if (spelling.EndsWith(suffix))
|
||||
spelling.RemoveFromEnd(suffix.Length);
|
||||
else if (spelling.StartsWith(suffix))
|
||||
spelling.RemoveFromStart(suffix.Length);
|
||||
|
||||
if (spelling == "Max")
|
||||
outString.Append("//");
|
||||
if (spelling[0].IsDigit)
|
||||
outString.Append('_');
|
||||
outString.Append(spelling);
|
||||
}
|
||||
else break;
|
||||
return;
|
||||
case .FunctionDecl:
|
||||
if (!IsInstanceMethod(cursor)) break;
|
||||
let arg = Clang.Cursor_GetArgument(cursor, 0);
|
||||
let handle = GetTypeSpelling!(Clang.GetCursorType(arg));
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
Runtime.Assert(spelling.StartsWith(handle));
|
||||
spelling.RemoveFromStart(handle.Length + 1);
|
||||
UpperSnakeCase2PascalCase(spelling, outString);
|
||||
return;
|
||||
default:
|
||||
}
|
||||
base.GetNameInBindings(cursor, outString);
|
||||
}
|
||||
|
||||
protected override void WriteToken(CXToken token)
|
||||
{
|
||||
let spelling = GetTokenSpelling!(token);
|
||||
if (Clang.GetTokenKind(token) == .Identifier && spelling == "spvc_bool")
|
||||
str.Append("SpvcBool");
|
||||
else if (Clang.GetTokenKind(token) == .Literal && spelling.Length == 9 && spelling.StartsWith("0x"))
|
||||
str.Append("0x0", spelling[2...]);
|
||||
else
|
||||
base.WriteToken(token);
|
||||
}
|
||||
|
||||
bool IsInstanceMethod(CXCursor cursor)
|
||||
{
|
||||
if (Clang.Cursor_GetNumArguments(cursor) < 1)
|
||||
return false;
|
||||
let arg = Clang.Cursor_GetArgument(cursor, 0);
|
||||
let type = GetTypeSpelling!(Clang.GetCursorType(arg));
|
||||
return handles.ContainsAlt(type);
|
||||
}
|
||||
|
||||
protected override void Method_Parameters(CXCursor cursor)
|
||||
{
|
||||
if (IsInstanceMethod(cursor))
|
||||
str.Append("this ");
|
||||
base.Method_Parameters(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
scope SpriVCrossGenerator(char8*[?]("--language=c")).Generate("../SPIRV-Cross/spirv_cross_c.h");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user