step towards c++
This commit is contained in:
+1
-1
@@ -164,7 +164,7 @@ static class Program
|
||||
}
|
||||
|
||||
Directory.CreateDirectory("clang-c");
|
||||
generator.Generate("clang-c.h", null);
|
||||
generator.Generate("clang-c.h");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+44
-169
@@ -64,6 +64,7 @@ abstract class Cpp2BeefGenerator
|
||||
}, &attrs);
|
||||
|
||||
if (Clang.GetCursorAvailability(cursor) == .Deprecated) str.Append("[Obsolete] ");
|
||||
//if (Clang.Cursor_IsFunctionInlined(cursor) != 0) str.Append("[Inline] ");
|
||||
if (cursor.kind == .EnumDecl) str.Append("[AllowDuplicates] ");
|
||||
else if (attrs.HasFlag(.Packed)) str.Append("[Packed] ");
|
||||
if (attrs.HasFlag(.NoDiscard)) str.Append("[NoDiscard] ");
|
||||
@@ -197,13 +198,10 @@ abstract class Cpp2BeefGenerator
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void ModifyWrapperPrintingPolicy(CXPrintingPolicy policy) {}
|
||||
|
||||
protected CXIndex index = Clang.CreateIndex(excludeDeclarationsFromPCH: 0, displayDiagnostics: 1) ~ Clang.DisposeIndex(_);
|
||||
protected CXTranslationUnit unit;
|
||||
|
||||
protected append String str = .(1024);
|
||||
protected append String wrapperBuf = .(1024);
|
||||
protected CXCursor currentCursor = Clang.GetNullCursor();
|
||||
protected append String cursorIndent = .(16);
|
||||
|
||||
@@ -213,8 +211,6 @@ abstract class Cpp2BeefGenerator
|
||||
protected CXPrintingPolicy printingPolicy;
|
||||
|
||||
private StreamWriter currentWritter;
|
||||
private StreamWriter wrapperWritter;
|
||||
protected StringView WrapperFilePath;
|
||||
|
||||
private append String wrapperTemplateChain = .(16);
|
||||
private append String templateParams = .(16);
|
||||
@@ -229,7 +225,7 @@ abstract class Cpp2BeefGenerator
|
||||
protected class FileInfo : this(CXSourceLocation prevEnd, CXFile file)
|
||||
{
|
||||
public append String block = .(64);
|
||||
public enum { None = 0, LSquirly = 1, RSquirly = 0b10 } queuedTokens = .None;
|
||||
public enum { None = 0, LSquirly = 1, RSquirly = _<<1, Semicolon = _<<1 } queuedTokens = .None;
|
||||
public (CXType type, int32 curWidth) bitfield = default;
|
||||
}
|
||||
protected FileInfo fileInfo = null;
|
||||
@@ -279,40 +275,12 @@ abstract class Cpp2BeefGenerator
|
||||
ParsingFailed
|
||||
}
|
||||
|
||||
public Result<void, GenerationError> Generate(char8* headerPath, StringView wrapperPath = null)
|
||||
public Result<void, GenerationError> Generate(char8* headerPath)
|
||||
{
|
||||
unitMacros.Clear();
|
||||
fileInfos.Clear();
|
||||
lastRecordOrEnum = Clang.GetNullCursor();
|
||||
|
||||
if (!wrapperPath.IsNull)
|
||||
{
|
||||
wrapperWritter = scope:: .();
|
||||
wrapperWritter.Create(wrapperPath);
|
||||
WrapperFilePath = wrapperPath;
|
||||
wrapperBuf.Set("""
|
||||
#define private public
|
||||
#define protected public
|
||||
|
||||
#include "
|
||||
""");
|
||||
Path.GetFileName(.(headerPath), wrapperBuf);
|
||||
wrapperBuf.Append("""
|
||||
"
|
||||
#include <stdint.h>
|
||||
|
||||
template <typename T>
|
||||
using __type = T;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
""");
|
||||
FlushWrapper();
|
||||
}
|
||||
else
|
||||
wrapperWritter = null;
|
||||
|
||||
let args = Args;
|
||||
#if DEBUG
|
||||
findLang: do
|
||||
@@ -331,7 +299,7 @@ abstract class Cpp2BeefGenerator
|
||||
if (unit == default) return .Err(.ParsingFailed);
|
||||
|
||||
printingPolicy = Clang.GetCursorPrintingPolicy(Clang.GetTranslationUnitCursor(unit));
|
||||
ModifyWrapperPrintingPolicy(printingPolicy);
|
||||
Clang.PrintingPolicy_SetProperty(printingPolicy, .TerseOutput, 1);
|
||||
defer Clang.PrintingPolicy_Dispose(printingPolicy);
|
||||
|
||||
PreGeneration();
|
||||
@@ -371,9 +339,6 @@ abstract class Cpp2BeefGenerator
|
||||
}, Internal.UnsafeCastToPtr(this));
|
||||
PostGeneration();
|
||||
|
||||
if (wrapperBuf.IsEmpty)
|
||||
wrapperWritter.Write("}\n\n//begin-comptime\n");
|
||||
|
||||
for (let kv in fileInfos)
|
||||
{
|
||||
fileInfo = kv.value;
|
||||
@@ -462,11 +427,6 @@ abstract class Cpp2BeefGenerator
|
||||
currentWritter.Write(str);
|
||||
str.Clear();
|
||||
}
|
||||
protected void FlushWrapper()
|
||||
{
|
||||
wrapperWritter.Write(wrapperBuf);
|
||||
wrapperBuf.Clear();
|
||||
}
|
||||
|
||||
protected virtual void GetIndentation(CXSourceLocation location, String outString)
|
||||
{
|
||||
@@ -627,6 +587,8 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
QueuedToken!(decltype(fileInfo.queuedTokens).LSquirly, "{");
|
||||
QueuedToken!(decltype(fileInfo.queuedTokens).RSquirly, "}");
|
||||
if (!fileInfo.queuedTokens.HasFlag(.RSquirly))
|
||||
QueuedToken!(decltype(fileInfo.queuedTokens).Semicolon, ";");
|
||||
|
||||
if (!isWritingQueuedToken) continue;
|
||||
if (fileInfo.queuedTokens == .None) block = @block;
|
||||
@@ -866,22 +828,18 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
const int int_maxDigits = scope $"{int.MaxValue:X}".Length + 1;
|
||||
protected virtual void CppWrapperName(CXCursor cursor, String outString)
|
||||
{
|
||||
String hashCode = ScopeCXString!(Clang.GetCursorUSR(cursor))
|
||||
.GetHashCode().ToString(..scope .(int_maxDigits), "X", null);
|
||||
outString.Append("cpp2beef_");
|
||||
if (hashCode.StartsWith('-')) hashCode[0] = 'm';
|
||||
outString.Append('0', int_maxDigits - hashCode.Length);
|
||||
outString.Append(hashCode);
|
||||
}
|
||||
|
||||
protected virtual enum { C, Cpp } Linkable_Attributes(CXCursor cursor)
|
||||
{
|
||||
let mangledName = ScopeCXString!(Clang.Cursor_GetMangling(cursor));
|
||||
let name = GetNameInBindings(cursor, ..scope .(mangledName.Length));
|
||||
WriteCustomAttributes(cursor);
|
||||
void LinkNameWhitespace()
|
||||
{
|
||||
if (Flags.HasFlag(.PreseveColumns))
|
||||
str..Append('\n')..Append(cursorIndent);
|
||||
else
|
||||
str.Append(' ');
|
||||
}
|
||||
if (mangledName == name)
|
||||
{
|
||||
str.Append("[CLink] ");
|
||||
@@ -891,20 +849,16 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
str.Append("[LinkName(");
|
||||
mangledName.QuoteString(str);
|
||||
str.Append(")] ");
|
||||
str.Append(")]");
|
||||
LinkNameWhitespace();
|
||||
return .C;
|
||||
}
|
||||
else
|
||||
{
|
||||
str.Append("[LinkName(\"");
|
||||
CppWrapperName(cursor, str);
|
||||
str.Append('"');
|
||||
if (!wrapperTemplateChain.IsEmpty)
|
||||
if (templateParams.IsEmpty)
|
||||
str.Append(" + __template_chain");
|
||||
else
|
||||
str.Append(" + CppWrapperF($\"", wrapperTemplateChain, "\")");
|
||||
str.Append(")] ");
|
||||
str.Append("[LinkName(");
|
||||
ScopeCXString!(Clang.GetCursorPrettyPrinted(cursor, printingPolicy)).QuoteString(str);
|
||||
str.Append(")]");
|
||||
LinkNameWhitespace();
|
||||
return .Cpp;
|
||||
}
|
||||
}
|
||||
@@ -1111,89 +1065,9 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void WriteMethodWrapper(CXCursor cursor)
|
||||
{
|
||||
let parent = Clang.GetCursorType(Clang.GetCursorSemanticParent(cursor));
|
||||
var resultType = Clang.GetCursorResultType(cursor);
|
||||
bool nonStatic = (cursor.kind == .CXXMethod && Clang.CXXMethod_IsStatic(cursor) == 0) || cursor.kind == .Destructor || cursor.kind == .ConversionFunction;
|
||||
|
||||
if (!wrapperTemplateChain.IsEmpty)
|
||||
FlushWrapper();
|
||||
StringView parentSpelling = "\" + __cpp_type + \"";
|
||||
if (wrapperTemplateChain.IsEmpty)
|
||||
parentSpelling = ScopeCXString!::(Clang.GetFullyQualifiedName(parent, printingPolicy, 0));
|
||||
|
||||
if (cursor.kind == .Constructor)
|
||||
wrapperBuf.Append("__type<", parentSpelling, "> ");
|
||||
else
|
||||
{
|
||||
wrapperBuf.Append("__type<");
|
||||
wrapperBuf.Append(ScopeCXString!(Clang.GetFullyQualifiedName(resultType, printingPolicy, 0)));
|
||||
wrapperBuf.Append("> ");
|
||||
}
|
||||
CppWrapperName(cursor, wrapperBuf);
|
||||
if (!wrapperTemplateChain.IsEmpty)
|
||||
{
|
||||
if (templateParams.IsEmpty)
|
||||
wrapperBuf.Append("\" + __template_chain + \"");
|
||||
else
|
||||
wrapperBuf.Append("\" + CppWrapperF($\"", wrapperTemplateChain, "\") + \"");
|
||||
}
|
||||
wrapperBuf.Append('(');
|
||||
if (nonStatic)
|
||||
wrapperBuf.Append(parentSpelling, " *self");
|
||||
for (int i < Clang.Cursor_GetNumArguments(cursor))
|
||||
{
|
||||
let arg = Clang.Cursor_GetArgument(cursor, (.)i);
|
||||
if (nonStatic || i > 0) wrapperBuf.Append(", ");
|
||||
wrapperBuf.Append("__type<");
|
||||
wrapperBuf.Append(ScopeCXString!(Clang.GetFullyQualifiedName(Clang.GetCursorType(arg), printingPolicy, 0)));
|
||||
wrapperBuf.Append("> p");
|
||||
i.ToString(wrapperBuf);
|
||||
}
|
||||
wrapperBuf.Append(") { ");
|
||||
if (resultType.kind != .Void) wrapperBuf.Append("return ");
|
||||
if (nonStatic)
|
||||
{
|
||||
if (cursor.kind != .Destructor)
|
||||
wrapperBuf.Append("self->", GetCursorSpelling!(cursor));
|
||||
else
|
||||
wrapperBuf.Append("self->~", parentSpelling);
|
||||
}
|
||||
else if (cursor.kind == .Constructor)
|
||||
wrapperBuf.Append("return ", parentSpelling);
|
||||
else
|
||||
wrapperBuf.Append(fullCursorName);
|
||||
wrapperBuf.Append('(');
|
||||
for (int i < Clang.Cursor_GetNumArguments(cursor))
|
||||
{
|
||||
if (i > 0) wrapperBuf.Append(", ");
|
||||
wrapperBuf.Append('p');
|
||||
i.ToString(wrapperBuf);
|
||||
}
|
||||
wrapperBuf.Append("); }");
|
||||
|
||||
if (wrapperTemplateChain.IsEmpty)
|
||||
{
|
||||
wrapperBuf.Append('\n');
|
||||
FlushWrapper();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defferedWrapperWrite == null)
|
||||
defferedWrapperWrite = new .(1024);
|
||||
defferedWrapperWrite.Append(cursorIndent, "\t + \"extern \\\"C\\\" ");
|
||||
wrapperBuf.ToString(defferedWrapperWrite);
|
||||
defferedWrapperWrite.Append("\\n\"\n");
|
||||
wrapperBuf.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void FunctionDecl(CXCursor cursor)
|
||||
{
|
||||
if (Linkable_Attributes(cursor) == .Cpp)
|
||||
WriteMethodWrapper(cursor);
|
||||
|
||||
Linkable_Attributes(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("static extern ");
|
||||
WriteTypeAndName(cursor, Clang.GetCursorResultType(cursor));
|
||||
@@ -1208,8 +1082,7 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
void Attributes()
|
||||
{
|
||||
if (Linkable_Attributes(cursor) == .Cpp)
|
||||
WriteMethodWrapper(cursor);
|
||||
Linkable_Attributes(cursor);
|
||||
}
|
||||
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
@@ -1345,18 +1218,6 @@ abstract class Cpp2BeefGenerator
|
||||
if (linkLang == .Cpp && type.kind != .LValueReference && type.kind != .RValueReference)
|
||||
str.Append("ref ");
|
||||
WriteTypeAndName(cursor, type);
|
||||
if (linkLang == .Cpp)
|
||||
{
|
||||
let wrapperName = CppWrapperName(cursor, ..scope .());
|
||||
str.Append(" { [LinkName(\"", wrapperName, "\")] get; }");
|
||||
wrapperBuf.Append("__type<");
|
||||
wrapperBuf.Append(ScopeCXString!(Clang.GetFullyQualifiedName(type, printingPolicy, 0)));
|
||||
wrapperBuf.Append("> ");
|
||||
if (type.kind != .LValueReference && type.kind != .RValueReference)
|
||||
wrapperBuf.Append('&');
|
||||
wrapperBuf.Append(wrapperName, "() { return ", fullCursorName, "; }\n");
|
||||
FlushWrapper();
|
||||
}
|
||||
str.Append(';');
|
||||
default:
|
||||
Runtime.FatalError(scope $"Unhandled var linkage: {_}");
|
||||
@@ -1381,15 +1242,16 @@ abstract class Cpp2BeefGenerator
|
||||
}, null) != 0;
|
||||
}
|
||||
|
||||
protected virtual void Record(CXCursor cursor)
|
||||
protected virtual void Record(CXCursor cursor, bool attributes = true)
|
||||
{
|
||||
WriteCustomAttributes(cursor);
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .StructDecl, .ClassDecl: str.Append("[CRepr] ");
|
||||
case .UnionDecl: str.Append("[CRepr, Union] ");
|
||||
default: Runtime.FatalError("Unhandled record type");
|
||||
}
|
||||
if (attributes)
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .StructDecl, .ClassDecl: str.Append("[CRepr] ");
|
||||
case .UnionDecl: str.Append("[CRepr, Union] ");
|
||||
default: Runtime.FatalError("Unhandled record type");
|
||||
}
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("struct ");
|
||||
if (Clang.Cursor_IsAnonymous(cursor) == 0)
|
||||
@@ -1483,9 +1345,22 @@ abstract class Cpp2BeefGenerator
|
||||
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(";");
|
||||
{
|
||||
self.BeginCursor(cursor);
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .StructDecl, .ClassDecl: self.str.Append("[CRepr] ");
|
||||
case .UnionDecl: self.str.Append("[CRepr, Union] ");
|
||||
default: Runtime.FatalError("Unhandled record type");
|
||||
}
|
||||
self.AccessSpecifier(cursor);
|
||||
self.str.Append("using ");
|
||||
self.Record(cursor, attributes: false);
|
||||
self.fileInfo.queuedTokens |= .Semicolon;
|
||||
}
|
||||
else
|
||||
self.WriteCursor(cursor);
|
||||
return .Continue;
|
||||
}, Internal.UnsafeCastToPtr(this));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user