c part ready to go
This commit is contained in:
+171
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Cpp2Beef;
|
||||
using LibClang;
|
||||
|
||||
namespace ClangC.Setup;
|
||||
|
||||
class ClangCGenerator : Cpp2BeefGenerator, this(Span<char8*> args)
|
||||
{
|
||||
protected override Span<char8*> Args => args;
|
||||
protected override Cpp2BeefGenerator.Flags Flags => .None;
|
||||
|
||||
public Dictionary<String, StreamWriter> writers = new .(8) ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
protected override StreamWriter GetWriterForHeader(StringView header)
|
||||
{
|
||||
if (header.IsNull || !header.Contains("clang-c")) return null;
|
||||
let headerPath = Path.GetActualPathName(header, ..scope .(header.Length));
|
||||
if (writers.TryAddAlt(headerPath, let keyPtr, let valuePtr))
|
||||
{
|
||||
String outPath = scope .(64);
|
||||
outPath.Append("../Cpp2Beef_dist/Clang-C/src/");
|
||||
Path.GetFileNameWithoutExtension(headerPath, outPath);
|
||||
outPath.Append(".bf");
|
||||
*keyPtr = new .(headerPath);
|
||||
*valuePtr = new .()..Create(outPath)..Write("""
|
||||
// This file was auto-generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
|
||||
namespace LibClang;
|
||||
|
||||
|
||||
""");
|
||||
}
|
||||
return *valuePtr;
|
||||
}
|
||||
|
||||
protected override Block GetCursorBlock(CXCursor cursor)
|
||||
{
|
||||
if (cursor.kind == .FunctionDecl)
|
||||
return .CustomBlock("Clang");
|
||||
return base.GetCursorBlock(cursor);
|
||||
}
|
||||
|
||||
protected override bool IsOutParam(CXCursor arg, CXCursor method)
|
||||
{
|
||||
let comment = Clang.Cursor_GetParsedComment(method);
|
||||
let spelling = GetCursorSpelling!(arg);
|
||||
for (let i < Clang.Comment_GetNumChildren(comment))
|
||||
{
|
||||
let param = Clang.Comment_GetChild(comment, i);
|
||||
if (Clang.Comment_GetKind(param) != .ParamCommand ||
|
||||
ScopeCXString!(Clang.ParamCommandComment_GetParamName(param)) != spelling) continue;
|
||||
let paragraph = Clang.BlockCommandComment_GetParagraph(param);
|
||||
if (Clang.Comment_GetNumChildren(paragraph) == 0) continue;
|
||||
let paragraphChild = Clang.Comment_GetChild(paragraph, 0);
|
||||
if (Clang.Comment_GetKind(paragraphChild) != .Text) continue;
|
||||
StringView paragraphText = ScopeCXString!(Clang.TextComment_GetText(paragraphChild));
|
||||
if (paragraphText..TrimStart().StartsWith("[out]")) return true;
|
||||
else break;
|
||||
}
|
||||
return base.IsOutParam(arg, method);
|
||||
}
|
||||
|
||||
protected override void GetNameInBindings(CXCursor cursor, String outString)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .FunctionDecl:
|
||||
StringView spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling.StartsWith("clang_")) spelling.RemoveFromStart(6);
|
||||
bool upper = true;
|
||||
for (let c in spelling)
|
||||
{
|
||||
if (upper)
|
||||
{
|
||||
outString.Append(c.ToUpper);
|
||||
upper = false;
|
||||
}
|
||||
else
|
||||
outString.Append(c);
|
||||
if (c == '_') upper = true;
|
||||
}
|
||||
case .EnumConstantDecl:
|
||||
let parentSpelling = GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor));
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
int i = 0;
|
||||
for (; i < parentSpelling.Length && i < spelling.Length
|
||||
&& parentSpelling[i] == spelling[i]; i++) {}
|
||||
spelling.RemoveFromStart(i);
|
||||
if (spelling.StartsWith('_')) spelling.RemoveFromStart(1);
|
||||
Compiler.Identifier.GetSourceName(spelling, outString);
|
||||
default:
|
||||
base.GetNameInBindings(cursor, outString);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void HandleCursor(CXCursor cursor)
|
||||
{
|
||||
if (cursor.kind == .TypedefDecl) do
|
||||
{
|
||||
let type = Clang.GetTypedefDeclUnderlyingType(cursor);
|
||||
if (type.kind != .Pointer) break;
|
||||
let pointee = Clang.GetPointeeType(type);
|
||||
if (pointee.kind == .FunctionProto || pointee.kind == .FunctionNoProto ||
|
||||
(pointee.kind == .Void && GetCursorSpelling!(cursor) == "CXClientData")) break;
|
||||
BeginCursor(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("struct ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(" : int {}");
|
||||
return;
|
||||
}
|
||||
base.HandleCursor(cursor);
|
||||
}
|
||||
|
||||
protected override void WriteCustomAttributes(CXCursor cursor)
|
||||
{
|
||||
if (cursor.kind == .FunctionDecl)
|
||||
str.Append("[Import(Clang.dll)] ");
|
||||
base.WriteCustomAttributes(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static class Program
|
||||
{
|
||||
[CLink] extern static int32 system(char8*);
|
||||
|
||||
const String[?] clangFiles = .(
|
||||
"BuildSystem",
|
||||
"CXCompilationDatabase",
|
||||
"CXDiagnostic",
|
||||
"CXErrorCode",
|
||||
"CXFile",
|
||||
"CXSourceLocation",
|
||||
"CXString",
|
||||
"Documentation",
|
||||
"ExternC",
|
||||
"FatalErrorHandler",
|
||||
"Index",
|
||||
"Platform",
|
||||
"Rewrite",
|
||||
);
|
||||
const String clangHeaders = "./Clang-C/clang-c";
|
||||
const String IclangHeaders = "-IClang-C";
|
||||
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
ClangCGenerator generator = scope .(char8*[?]("--language=c", IclangHeaders));
|
||||
|
||||
Directory.CreateDirectory(clangHeaders);
|
||||
{
|
||||
StreamWriter includeAll = scope .()..Create("clang-c.h");
|
||||
for (let file in clangFiles)
|
||||
{
|
||||
//if (system(scope $"curl -o {clangHeaders}/{file}.h https://raw.githubusercontent.com/llvm/llvm-project/refs/heads/main/clang/include/clang-c/{file}.h") != 0)
|
||||
// Runtime.FatalError(scope $"Failed to download clang-c/{file}");
|
||||
includeAll.Write($"#include <clang-c/{file}.h>\n");
|
||||
}
|
||||
}
|
||||
|
||||
Directory.CreateDirectory("clang-c");
|
||||
generator.Generate("clang-c.h", null);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+135
-39
@@ -38,6 +38,8 @@ abstract class Cpp2BeefGenerator
|
||||
case "uint16_t": outString.Append("uint16");
|
||||
case "uint32_t": outString.Append("uint32");
|
||||
case "uint64_t": outString.Append("uint64");
|
||||
case "intptr_t": outString.Append("c_intptr");
|
||||
case "uintptr_t": outString.Append("c_uintptr");
|
||||
default: fallthrough getName;
|
||||
}
|
||||
default:
|
||||
@@ -93,7 +95,7 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBlock(Block block)
|
||||
protected void WriteBlock(Block block)
|
||||
{
|
||||
StringView target;
|
||||
switch (block)
|
||||
@@ -131,6 +133,8 @@ abstract class Cpp2BeefGenerator
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .StructDecl, .ClassDecl, .UnionDecl, .EnumDecl:
|
||||
if (Clang.Cursor_IsAnonymous(cursor) != 0)
|
||||
return;
|
||||
if (templateParams.IsEmpty && Clang.EqualCursors(cursor, Clang.GetTypeDeclaration(Clang.GetCursorType(cursor))) == 0)
|
||||
return;
|
||||
BeginCursor(cursor);
|
||||
@@ -170,7 +174,7 @@ abstract class Cpp2BeefGenerator
|
||||
MacroDefinition(cursor);
|
||||
|
||||
case .InclusionDirective, .MacroExpansion, .CXXBaseSpecifier, .CXXAccessSpecifier,
|
||||
.LinkageSpec, .TemplateTypeParameter, .NonTypeTemplateParameter: // ignored
|
||||
.LinkageSpec, .TemplateTypeParameter, .NonTypeTemplateParameter, .StaticAssert: // ignored
|
||||
default: Debug.WriteLine(scope $"Unhandled cursor: {_}");
|
||||
}
|
||||
}
|
||||
@@ -222,7 +226,8 @@ abstract class Cpp2BeefGenerator
|
||||
protected class FileInfo : this(CXSourceLocation prevEnd, CXFile file)
|
||||
{
|
||||
public append String block = .(64);
|
||||
public enum { None, LSquirly, RSquirly } queuedToken = .None;
|
||||
public enum { None = 0, LSquirly = 1, RSquirly = 0b10 } queuedTokens = .None;
|
||||
public (CXType type, int32 curWidth) bitfield = default;
|
||||
}
|
||||
protected FileInfo fileInfo = null;
|
||||
private Dictionary<String, FileInfo> fileInfos = new .(32) ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
@@ -251,6 +256,18 @@ abstract class Cpp2BeefGenerator
|
||||
ScopeCXString!:mixin(Clang.GetTokenSpelling(unit, token))
|
||||
}
|
||||
|
||||
public static void UpperSnakeCase2PascalCase(StringView snakeCase, String outString)
|
||||
{
|
||||
bool upper = true;
|
||||
for (let c in snakeCase)
|
||||
if (c == '_') upper = true;
|
||||
else
|
||||
{
|
||||
outString.Append(upper ? c.ToUpper : c.ToLower);
|
||||
upper = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void PreGeneration() {}
|
||||
protected virtual void PostGeneration() {}
|
||||
|
||||
@@ -305,8 +322,8 @@ abstract class Cpp2BeefGenerator
|
||||
#endif
|
||||
CXTranslationUnit_Flags unitFlags = .SkipFunctionBodies | .DetailedPreprocessingRecord;
|
||||
unit = Clang.ParseTranslationUnit(index, headerPath, args.Ptr, (.)args.Length, null, 0, (.)unitFlags);
|
||||
if (unit == null) return .Err(.ParsingFailed);
|
||||
|
||||
if (unit == default) return .Err(.ParsingFailed);
|
||||
|
||||
printingPolicy = Clang.GetCursorPrintingPolicy(Clang.GetTranslationUnitCursor(unit));
|
||||
ModifyWrapperPrintingPolicy(printingPolicy);
|
||||
defer Clang.PrintingPolicy_Dispose(printingPolicy);
|
||||
@@ -318,14 +335,14 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
{
|
||||
let location = Clang.GetCursorLocation(cursor);
|
||||
Clang.GetSpellingLocation(location, let file, let line, ?, ?);
|
||||
Clang.GetFileLocation(location, let file, let line, ?, ?);
|
||||
let header = ScopeCXString!(Clang.GetFileName(file));
|
||||
self.currentWritter = self.GetWriterForHeader(header);
|
||||
if (self.currentWritter == null) return .Continue;
|
||||
|
||||
if (cursor.kind == .MacroDefinition)
|
||||
{
|
||||
self.unitMacros.Add(.(line, file), cursor);
|
||||
self.unitMacros[.(line, file)] = cursor;
|
||||
return .Continue;
|
||||
}
|
||||
|
||||
@@ -429,7 +446,7 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
protected void FatalErrorMsg(String outString)
|
||||
{
|
||||
Clang.GetSpellingLocation(Clang.GetCursorLocation(currentCursor), let file, let line, let col, ?);
|
||||
Clang.GetFileLocation(Clang.GetCursorLocation(currentCursor), let file, let line, let col, ?);
|
||||
outString.Append("in cursor '", GetCursorSpelling!(currentCursor), "' at line ");
|
||||
outString.AppendF($"{line}:{col}");
|
||||
outString.Append(" in file ", GetFilePath!(file));
|
||||
@@ -451,7 +468,7 @@ abstract class Cpp2BeefGenerator
|
||||
StringView file;
|
||||
uint32 offset;
|
||||
{
|
||||
Clang.GetSpellingLocation(location, let cxfile, ?, ?, out offset);
|
||||
Clang.GetFileLocation(location, let cxfile, ?, ?, out offset);
|
||||
char8* ptr = Clang.GetFileContents(unit, cxfile, let size);
|
||||
file = .(ptr, (.)size);
|
||||
}
|
||||
@@ -467,7 +484,7 @@ abstract class Cpp2BeefGenerator
|
||||
StringView file;
|
||||
uint32 offset;
|
||||
{
|
||||
Clang.GetSpellingLocation(from, let cxfile, ?, ?, out offset);
|
||||
Clang.GetFileLocation(from, let cxfile, ?, ?, out offset);
|
||||
char8* ptr = Clang.GetFileContents(unit, cxfile, let size);
|
||||
file = .(ptr, (.)size);
|
||||
}
|
||||
@@ -487,8 +504,8 @@ abstract class Cpp2BeefGenerator
|
||||
Clang.EqualLocations(end, Clang.GetNullLocation()) != 0) return;
|
||||
|
||||
StringView file;
|
||||
Clang.GetSpellingLocation(start, let startFile, ?, ?, let startOffset);
|
||||
Clang.GetSpellingLocation(end, let endfile, ?, ?, let endOffset);
|
||||
Clang.GetFileLocation(start, let startFile, ?, ?, let startOffset);
|
||||
Clang.GetFileLocation(end, let endfile, ?, ?, let endOffset);
|
||||
if (Clang.File_IsEqual(startFile, endfile) == 0) return;
|
||||
char8* ptr = Clang.GetFileContents(unit, startFile, let size);
|
||||
file = .(ptr, (.)size);
|
||||
@@ -501,24 +518,35 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual CXSourceLocation GetCursorAnchor(CXCursor cursor)
|
||||
{
|
||||
let cursorLocation = Clang.GetCursorLocation(cursor);
|
||||
//let rangeLocation = Clang.GetRangeStart(Clang.GetCursorExtent(cursor));
|
||||
//if (Clang.File_IsEqual(Clang.GetSpellingLocation(cursorLocation, file: ..?, ?, ?, ?), Clang.GetSpellingLocation(rangeLocation, file: ..?, ?, ?, ?)) == 0)
|
||||
return cursorLocation;
|
||||
//return rangeLocation;
|
||||
}
|
||||
|
||||
protected virtual void WriteComments(CXCursor cursor, Block? block = null)
|
||||
{
|
||||
let location = GetCursorAnchor(cursor);
|
||||
if (cursor.kind == .MacroDefinition)
|
||||
{
|
||||
GetIndentation(Clang.GetCursorLocation(cursor), str);
|
||||
if (block.HasValue) WriteBlock(block.Value);
|
||||
GetIndentation(location, str);
|
||||
return;
|
||||
}
|
||||
cursorIndent.Clear();
|
||||
GetIndentation(Clang.GetCursorLocation(cursor), cursorIndent);
|
||||
WriteComments(Clang.GetCursorLocation(cursor), block);
|
||||
GetIndentation(location, cursorIndent);
|
||||
WriteComments(location, block);
|
||||
}
|
||||
protected virtual void WriteComments(CXSourceLocation writeUntil, Block? block = null)
|
||||
{
|
||||
Clang.GetSpellingLocation(writeUntil, let curFile, let curLine, let curColumn, let curOffset);
|
||||
Clang.GetSpellingLocation(fileInfo.prevEnd, let prevFile, let prevLine, let prevColumn, let prevOffset);
|
||||
Clang.GetFileLocation(writeUntil, let curFile, let curLine, let curColumn, let curOffset);
|
||||
Clang.GetFileLocation(fileInfo.prevEnd, let prevFile, let prevLine, let prevColumn, let prevOffset);
|
||||
|
||||
defer { fileInfo.prevEnd = writeUntil; }
|
||||
if (Clang.File_IsEqual(curFile, prevFile) == 0) Runtime.FatalError();
|
||||
if (Clang.File_IsEqual(curFile, prevFile) == 0) Runtime.FatalError(scope $"{GetFilePath!(curFile)} != {GetFilePath!(prevFile)}");
|
||||
|
||||
var between = Clang.GetRange(
|
||||
Clang.GetLocationForOffset(unit, prevFile, prevOffset),
|
||||
@@ -579,18 +607,23 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
case .Comment:
|
||||
case .Punctuation:
|
||||
switch (fileInfo.queuedToken)
|
||||
mixin QueuedToken(var queuedToken, StringView spelling)
|
||||
{
|
||||
case .LSquirly: if (GetTokenSpelling!(token) != "{") continue;
|
||||
case .RSquirly: if (GetTokenSpelling!(token) != "}") continue;
|
||||
case .None: continue;
|
||||
if (fileInfo.queuedTokens.HasFlag(queuedToken) && GetTokenSpelling!(token) == spelling)
|
||||
{
|
||||
fileInfo.queuedTokens ^= queuedToken;
|
||||
isWritingQueuedToken = true;
|
||||
}
|
||||
}
|
||||
fileInfo.queuedToken = .None;
|
||||
isWritingQueuedToken = true;
|
||||
|
||||
QueuedToken!(decltype(fileInfo.queuedTokens).LSquirly, "{");
|
||||
QueuedToken!(decltype(fileInfo.queuedTokens).RSquirly, "}");
|
||||
|
||||
if (!isWritingQueuedToken) continue;
|
||||
default: continue;
|
||||
}
|
||||
let location = Clang.GetTokenLocation(unit, token);
|
||||
Clang.GetSpellingLocation(location, ?, let startLine, ?, ?);
|
||||
Clang.GetFileLocation(location, ?, let startLine, ?, ?);
|
||||
WriteLinesUntil!(startLine, location);
|
||||
if (!isWritingQueuedToken)
|
||||
{
|
||||
@@ -671,6 +704,13 @@ abstract class Cpp2BeefGenerator
|
||||
case .StructDecl, .ClassDecl, .UnionDecl: Record(decl);
|
||||
default: Runtime.FatalError(scope $"Unhandled anon type: {_}");
|
||||
}
|
||||
if (fileInfo.queuedTokens.HasFlag(.RSquirly))
|
||||
{
|
||||
str.Append('\n');
|
||||
GetIndentation(GetCursorAnchor(decl), str);
|
||||
str.Append('}');
|
||||
fileInfo.queuedTokens ^= .RSquirly;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -751,6 +791,7 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
if (Clang.GetTokenKind(token) == .Punctuation && { let spelling = GetTokenSpelling!(token); spelling == "," || spelling == ")" })
|
||||
{
|
||||
if (Clang.GetTokenKind(last) != .Identifier) break;
|
||||
str.Append(' ');
|
||||
str.Append(GetTokenSpelling!(last));
|
||||
break;
|
||||
@@ -779,26 +820,27 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
protected mixin BeginBody(CXCursor cursor)
|
||||
{
|
||||
fileInfo.prevEnd = Clang.GetCursorLocation(cursor);
|
||||
fileInfo.queuedToken = .LSquirly;
|
||||
fileInfo.prevEnd = GetCursorAnchor(cursor);
|
||||
fileInfo.queuedTokens |= .LSquirly;
|
||||
|
||||
// [Friend] is needed in case you use BeginBody! in your code
|
||||
if (canChangeBlock)
|
||||
{
|
||||
defer:mixin { canChangeBlock = true; }
|
||||
canChangeBlock = false;
|
||||
defer:mixin { this.[Friend]canChangeBlock = true; }
|
||||
this.[Friend]canChangeBlock = false;
|
||||
}
|
||||
|
||||
defer:mixin
|
||||
{
|
||||
if (defferedWrapperWrite != null)
|
||||
if (this.[Friend]defferedWrapperWrite != null)
|
||||
{
|
||||
str.Append("\n\n", cursorIndent, "const String _wrapperText = \"\\n\"\n",
|
||||
defferedWrapperWrite, ";");
|
||||
delete defferedWrapperWrite;
|
||||
defferedWrapperWrite = null;
|
||||
this.[Friend]defferedWrapperWrite, ";");
|
||||
delete this.[Friend]defferedWrapperWrite;
|
||||
this.[Friend]defferedWrapperWrite = null;
|
||||
}
|
||||
|
||||
if (fileInfo.queuedToken == .LSquirly)
|
||||
if (fileInfo.queuedTokens.HasFlag(.LSquirly))
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
@@ -807,11 +849,10 @@ abstract class Cpp2BeefGenerator
|
||||
default:
|
||||
str.Append(" {}");
|
||||
}
|
||||
fileInfo.queuedToken = .None;
|
||||
fileInfo.queuedTokens = .None;
|
||||
}
|
||||
else
|
||||
fileInfo.queuedToken = .RSquirly;
|
||||
|
||||
fileInfo.queuedTokens |= .RSquirly;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,7 +1094,7 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
if (Clang.Cursor_IsInlineNamespace(cursor) != 0)
|
||||
{
|
||||
GetIndentation(Clang.GetCursorLocation(cursor), str);
|
||||
GetIndentation(GetCursorAnchor(cursor), str);
|
||||
str.Append("public static using ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(";\n");
|
||||
@@ -1215,11 +1256,61 @@ abstract class Cpp2BeefGenerator
|
||||
str.Append(';');
|
||||
}
|
||||
|
||||
int bitfieldUniquenessCounter = 0;
|
||||
protected virtual void DumpBitfieldStorage()
|
||||
{
|
||||
str.Append("\n", cursorIndent, "private ");
|
||||
Type(fileInfo.bitfield.type);
|
||||
str.Append(" __bitfield_");
|
||||
bitfieldUniquenessCounter++.ToString(str);
|
||||
str.Append(';');
|
||||
fileInfo.bitfield = default;
|
||||
}
|
||||
|
||||
protected virtual void FieldDecl(CXCursor cursor)
|
||||
{
|
||||
let type = Clang.GetCursorType(cursor);
|
||||
if (Clang.Cursor_IsBitField(cursor) != 0)
|
||||
{
|
||||
if (fileInfo.bitfield.type != default && Clang.EqualTypes(fileInfo.bitfield.type, type) == 0)
|
||||
DumpBitfieldStorage();
|
||||
if (fileInfo.bitfield == default)
|
||||
fileInfo.bitfield.type = type;
|
||||
int32 width = Clang.GetFieldDeclBitWidth(cursor);
|
||||
Debug.Assert(width <= Clang.Type_GetSizeOf(type) * 8);
|
||||
fileInfo.bitfield.curWidth += width;
|
||||
if (fileInfo.bitfield.curWidth > Clang.Type_GetSizeOf(type) * 8)
|
||||
{
|
||||
DumpBitfieldStorage();
|
||||
fileInfo.bitfield.curWidth = width;
|
||||
}
|
||||
|
||||
str.Append("[Bitfield(.");
|
||||
if (GetCursorSpelling!(cursor).IsEmpty)
|
||||
{
|
||||
str.Append("Private, .Bits(");
|
||||
width.ToString(str);
|
||||
str.Append("), \"__anon_bitfield_");
|
||||
bitfieldUniquenessCounter++.ToString(str);
|
||||
str.Append("\")]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Flush();
|
||||
AccessSpecifier(cursor);
|
||||
str[0] = str[0].ToUpper;
|
||||
str.Append(", .Bits(");
|
||||
width.ToString(str);
|
||||
str.Append("), \"");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append("\")]");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
WriteCustomAttributes(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
WriteTypeAndName(cursor, Clang.GetCursorType(cursor));
|
||||
WriteTypeAndName(cursor, type);
|
||||
str.Append(';');
|
||||
}
|
||||
|
||||
@@ -1380,11 +1471,16 @@ abstract class Cpp2BeefGenerator
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
Self self = (.)Internal.UnsafeCastToObject(client_data);
|
||||
if (self.fileInfo.bitfield != default && Clang.Cursor_IsBitField(cursor) == 0)
|
||||
self.DumpBitfieldStorage();
|
||||
self.WriteCursor(cursor);
|
||||
if (Clang.Cursor_IsAnonymousRecordDecl(cursor) != 0)
|
||||
self.str..TrimEnd()..Append(";");
|
||||
return .Continue;
|
||||
}, Internal.UnsafeCastToPtr(this));
|
||||
|
||||
if (fileInfo.bitfield != default)
|
||||
DumpBitfieldStorage();
|
||||
}
|
||||
|
||||
protected virtual void Enum(CXCursor cursor)
|
||||
|
||||
Reference in New Issue
Block a user