port stub
This commit is contained in:
+132
-55
@@ -17,6 +17,9 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
None = 0,
|
||||
PreseveColumns = 1,
|
||||
|
||||
/// WIP
|
||||
Port = 2,
|
||||
}
|
||||
|
||||
protected virtual void GetNameInBindings(CXCursor cursor, String outString)
|
||||
@@ -156,7 +159,7 @@ abstract class Cpp2BeefGenerator
|
||||
case .FunctionDecl: BeginCursor(cursor); FunctionDecl(cursor);
|
||||
|
||||
case .FunctionTemplate, .ClassTemplate, .TypeAliasTemplateDecl:
|
||||
Runtime.FatalError("Templates are currently unsupported but Coming Soon tm");
|
||||
Internal.FatalError(scope $"Templates are currently unsupported but Coming Soon tm {FatalErrorMsg(..scope .(256))}");
|
||||
|
||||
case .CXXMethod,
|
||||
.Constructor,
|
||||
@@ -225,8 +228,10 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
protected class FileInfo : this(CXSourceLocation prevEnd, CXFile file)
|
||||
{
|
||||
public enum QueuedTokens { None = 0, LSquirly = 1, RSquirly = _<<1, Semicolon = _<<1 }
|
||||
|
||||
public append String block = .(64);
|
||||
public enum { None = 0, LSquirly = 1, RSquirly = _<<1, Semicolon = _<<1 } queuedTokens = .None;
|
||||
public QueuedTokens queuedTokens = .None;
|
||||
public (CXType type, int32 curWidth) bitfield = default;
|
||||
}
|
||||
protected FileInfo fileInfo = null;
|
||||
@@ -295,7 +300,8 @@ abstract class Cpp2BeefGenerator
|
||||
Runtime.FatalError("You must set a language via Args (e.g. --language=c++)");
|
||||
}
|
||||
#endif
|
||||
CXTranslationUnit_Flags unitFlags = .SkipFunctionBodies | .DetailedPreprocessingRecord;
|
||||
CXTranslationUnit_Flags unitFlags = .DetailedPreprocessingRecord;
|
||||
if (!Flags.HasFlag(.Port)) unitFlags |= .SkipFunctionBodies;
|
||||
unit = Clang.ParseTranslationUnit(index, headerPath, args.Ptr, (.)args.Length, null, 0, (.)unitFlags);
|
||||
if (unit == default) return .Err(.ParsingFailed);
|
||||
|
||||
@@ -516,7 +522,8 @@ abstract class Cpp2BeefGenerator
|
||||
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(scope $"{GetFilePath!(curFile)} != {GetFilePath!(prevFile)}");
|
||||
if (!Flags.HasFlag(.Port) && Clang.File_IsEqual(curFile, prevFile) == 0)
|
||||
Internal.FatalError(scope $"{GetFilePath!(curFile)} does not match {GetFilePath!(prevFile)} {FatalErrorMsg(..scope .(256))}");
|
||||
|
||||
var between = Clang.GetRange(
|
||||
Clang.GetLocationForOffset(unit, prevFile, prevOffset),
|
||||
@@ -658,7 +665,8 @@ abstract class Cpp2BeefGenerator
|
||||
fallthrough;
|
||||
case .RValueReference:
|
||||
str.Append("in ");
|
||||
default: Runtime.FatalError();
|
||||
default:
|
||||
Internal.FatalError(scope $"Unhandled in-param cursor {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
case .OutParam: str.Append("out ");
|
||||
}
|
||||
@@ -676,7 +684,7 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
case .EnumDecl: Enum(decl);
|
||||
case .StructDecl, .ClassDecl, .UnionDecl: Record(decl);
|
||||
default: Runtime.FatalError(scope $"Unhandled anon type: {_}");
|
||||
default: Internal.FatalError(scope $"Unhandled anon type: {_} {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
if (fileInfo.queuedTokens.HasFlag(.RSquirly))
|
||||
{
|
||||
@@ -693,7 +701,7 @@ abstract class Cpp2BeefGenerator
|
||||
String buffer = scope .(256);
|
||||
GetNameInBindings(decl, qualified);
|
||||
CXCursor parent = decl;
|
||||
while (true)
|
||||
qualify: while (true)
|
||||
{
|
||||
parent = Clang.GetCursorSemanticParent(parent);
|
||||
if (Clang.IsDeclaration(parent.kind) == 0 || parent.kind == .LinkageSpec) break;
|
||||
@@ -705,22 +713,25 @@ abstract class Cpp2BeefGenerator
|
||||
buffer.Append('<');
|
||||
Clang.VisitChildren(parent, (cursor, parent, client_data) =>
|
||||
{
|
||||
String buffer = (.)Internal.UnsafeCastToObject(client_data);
|
||||
(Self self, String buffer) = *(.)client_data;
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .TemplateTypeParameter, .NonTypeTemplateParameter:
|
||||
case .TemplateTemplateParameter:
|
||||
Runtime.FatalError(scope $"C++ template template parameters are not supported");
|
||||
Internal.FatalError(scope $"C++ template template parameters are not supported {self.FatalErrorMsg(..scope .(256))}");
|
||||
default: return .Continue;
|
||||
}
|
||||
buffer.Append(GetCursorSpelling!(cursor), ", ");
|
||||
return .Continue;
|
||||
}, Internal.UnsafeCastToPtr(buffer));
|
||||
}, &(this, buffer));
|
||||
buffer.Length -= 2;
|
||||
buffer.Append('>');
|
||||
default:
|
||||
let parentType = Clang.GetCursorType(parent);
|
||||
if (parentType.kind == .Invalid) break qualify;
|
||||
|
||||
Flush();
|
||||
Type(Clang.GetCursorType(parent));
|
||||
Type(parentType);
|
||||
buffer.Append(str);
|
||||
str.Clear();
|
||||
}
|
||||
@@ -737,12 +748,16 @@ abstract class Cpp2BeefGenerator
|
||||
for (let i < numTemplateArgs)
|
||||
{
|
||||
if (i > 0) str.Append(", ");
|
||||
Type(Clang.Type_GetTemplateArgumentAsType(type, (.)i));
|
||||
let templateType = Clang.Type_GetTemplateArgumentAsType(type, (.)i);
|
||||
if (templateType.kind == .Invalid)
|
||||
str.Append(GetTypeSpelling!(type));
|
||||
else
|
||||
Type(templateType);
|
||||
}
|
||||
str.Append('>');
|
||||
}
|
||||
case .Unexposed, .DependentSizedArray: str.Append(ScopeCXString!(Clang.GetTypeSpelling(Clang.GetUnqualifiedType(type)))); // template param
|
||||
default: Runtime.FatalError(scope $"Unhandled type: {_} \"{GetTypeSpelling!(type)}\"");
|
||||
default: Internal.FatalError(scope $"Unhandled type: {_} \"{GetTypeSpelling!(type)}\" {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -799,8 +814,14 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
protected mixin BeginBody(CXCursor cursor)
|
||||
{
|
||||
static void SetQueuedTokens(FileInfo fileInfo, FileInfo.QueuedTokens queuedTokens)
|
||||
{
|
||||
fileInfo.queuedTokens |= queuedTokens;
|
||||
}
|
||||
|
||||
fileInfo.prevEnd = GetCursorAnchor(cursor);
|
||||
fileInfo.queuedTokens |= .LSquirly;
|
||||
defer:mixin SetQueuedTokens(fileInfo, fileInfo.queuedTokens);
|
||||
fileInfo.queuedTokens = .LSquirly;
|
||||
|
||||
// [Friend] is needed in case you use BeginBody! in your code
|
||||
if (canChangeBlock)
|
||||
@@ -837,8 +858,10 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual enum { C, Cpp } Linkable_Attributes(CXCursor cursor)
|
||||
protected enum LinkageLanguage { C, Cpp }
|
||||
protected virtual LinkageLanguage Linkable_Attributes(CXCursor cursor)
|
||||
{
|
||||
if (Flags.HasFlag(.Port)) return .C;
|
||||
let mangledName = ScopeCXString!(Clang.Cursor_GetMangling(cursor));
|
||||
let name = GetNameInBindings(cursor, ..scope .(mangledName.Length));
|
||||
WriteCustomAttributes(cursor);
|
||||
@@ -942,7 +965,7 @@ abstract class Cpp2BeefGenerator
|
||||
String typeStr = scope .(str);
|
||||
str.Clear();
|
||||
str.Append("operator", whitespace, typeStr, templateParams);
|
||||
case .Ctor: Runtime.FatalError();
|
||||
case .Ctor: Internal.FatalError(scope $"unhandled ctor {FatalErrorMsg(..scope .(256))}");
|
||||
case .Dtor: str.Append(whitespace, "Dispose");
|
||||
}
|
||||
}
|
||||
@@ -1075,6 +1098,35 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void PortCodeBody(CXCursor cursor)
|
||||
{
|
||||
if (!Flags.HasFlag(.Port))
|
||||
{
|
||||
str.Append(';');
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor;
|
||||
if (Clang.IsCursorDefinition(cursor) == 0)
|
||||
{
|
||||
cursor = Clang.GetCursorDefinition(cursor);
|
||||
if (Clang.Cursor_IsNull(cursor) != 0)
|
||||
{
|
||||
str.Append(';');
|
||||
return;
|
||||
}
|
||||
}
|
||||
BeginBody!(@cursor);
|
||||
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
Self self = *(.)client_data;
|
||||
self.BeginCursor(cursor);
|
||||
self.str.Append(ScopeCXString!(Clang.GetCursorPrettyPrinted(cursor, self.printingPolicy)));
|
||||
return .Continue;
|
||||
}, &(this, default(void)));
|
||||
}
|
||||
|
||||
protected virtual void FunctionDecl(CXCursor cursor)
|
||||
{
|
||||
Linkable_Attributes(cursor);
|
||||
@@ -1085,7 +1137,7 @@ abstract class Cpp2BeefGenerator
|
||||
Method_Parameters(cursor);
|
||||
str.Append(')');
|
||||
str.Append(templateParamsWhere);
|
||||
str.Append(';');
|
||||
PortCodeBody(cursor);
|
||||
}
|
||||
|
||||
protected virtual void CXXMethod(CXCursor cursor) //TODO: conversion function
|
||||
@@ -1100,7 +1152,8 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
if (spelling == "operator[]")
|
||||
{
|
||||
Runtime.Assert(templateParams.IsEmpty, "Properties can't have generics");
|
||||
if (!templateParams.IsEmpty)
|
||||
Internal.FatalError(scope $"Properties can't have generics {FatalErrorMsg(..scope .(256))}");
|
||||
AccessSpecifier(cursor);
|
||||
if (Clang.CXXMethod_IsStatic(cursor) != 0) str.Append("static ");
|
||||
str.Append("extern ");
|
||||
@@ -1123,7 +1176,7 @@ abstract class Cpp2BeefGenerator
|
||||
if (str.EndsWith(", ")) str.Length -= 2;
|
||||
str.Append(')');
|
||||
str.Append(templateParamsWhere);
|
||||
str.Append(';');
|
||||
PortCodeBody(cursor);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1138,7 +1191,7 @@ abstract class Cpp2BeefGenerator
|
||||
case .CXXMethod:
|
||||
WriteTypeAndName(cursor, Clang.GetCursorResultType(cursor));
|
||||
default:
|
||||
Runtime.FatalError("Unhandled c++ method kind");
|
||||
Internal.FatalError(scope $"Unhandled c++ method kind {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
str.Append('(');
|
||||
Method_Parameters(cursor);
|
||||
@@ -1146,7 +1199,7 @@ abstract class Cpp2BeefGenerator
|
||||
if (Clang.CXXMethod_IsStatic(cursor) == 0 && Clang.CXXMethod_IsConst(cursor) == 0 && cursor.kind == .CXXMethod)
|
||||
str.Append(" mut");
|
||||
str.Append(templateParamsWhere);
|
||||
str.Append(';');
|
||||
PortCodeBody(cursor);
|
||||
}
|
||||
|
||||
int bitfieldUniquenessCounter = 0;
|
||||
@@ -1213,24 +1266,30 @@ abstract class Cpp2BeefGenerator
|
||||
let type = Clang.GetCursorType(cursor);
|
||||
switch (Clang.GetCursorLinkage(cursor))
|
||||
{
|
||||
case .Internal when Clang.IsConstQualifiedType(type) != 0:
|
||||
case .Internal when Clang.IsConstQualifiedType(type) != 0
|
||||
|| ScopeCXString!(Clang.GetCursorPrettyPrinted(cursor, printingPolicy)).Contains("constexpr"):
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("const ");
|
||||
WriteTypeAndName(cursor, type);
|
||||
WriteTokensAfterEquals(cursor);
|
||||
str.Append(';');
|
||||
case .External, .UniqueExternal:
|
||||
Flush();
|
||||
let linkLang = Linkable_Attributes(cursor);
|
||||
if (linkLang == .Cpp) str.Clear();
|
||||
Linkable_Attributes(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("static extern ");
|
||||
if (linkLang == .Cpp && type.kind != .LValueReference && type.kind != .RValueReference)
|
||||
str.Append("ref ");
|
||||
WriteTypeAndName(cursor, type);
|
||||
str.Append(';');
|
||||
default:
|
||||
Runtime.FatalError(scope $"Unhandled var linkage: {_}");
|
||||
if (Flags.HasFlag(.Port))
|
||||
{
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("static ");
|
||||
WriteTypeAndName(cursor, type);
|
||||
WriteTokensAfterEquals(cursor);
|
||||
str.Append(';');
|
||||
}
|
||||
else
|
||||
Internal.FatalError(scope $"Unhandled var linkage: {_} {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,26 +1313,31 @@ abstract class Cpp2BeefGenerator
|
||||
|
||||
protected virtual void Record(CXCursor cursor, bool attributes = true)
|
||||
{
|
||||
bool port = Flags.HasFlag(.Port);
|
||||
WriteCustomAttributes(cursor);
|
||||
if (attributes)
|
||||
if (attributes && !port)
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .StructDecl, .ClassDecl: str.Append("[CRepr] ");
|
||||
case .UnionDecl: str.Append("[CRepr, Union] ");
|
||||
default: Runtime.FatalError("Unhandled record type");
|
||||
default: Internal.FatalError(scope $"Unhandled record type {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("struct ");
|
||||
if (cursor.kind == .ClassDecl && port)
|
||||
str.Append("class ");
|
||||
else
|
||||
str.Append("struct ");
|
||||
if (Clang.Cursor_IsAnonymous(cursor) == 0)
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(templateParams);
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
if (cursor.kind != .Destructor) return .Continue;
|
||||
String str = (.)Internal.UnsafeCastToObject(client_data);
|
||||
str.Append(" : IDisposable");
|
||||
return .Break;
|
||||
}, Internal.UnsafeCastToPtr(str));
|
||||
if (!port)
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
if (cursor.kind != .Destructor) return .Continue;
|
||||
String str = (.)Internal.UnsafeCastToObject(client_data);
|
||||
str.Append(" : IDisposable");
|
||||
return .Break;
|
||||
}, Internal.UnsafeCastToPtr(str));
|
||||
|
||||
str.Append(templateParamsWhere);
|
||||
BeginBody!(cursor);
|
||||
@@ -1293,7 +1357,7 @@ abstract class Cpp2BeefGenerator
|
||||
}
|
||||
}, Internal.UnsafeCastToPtr(this));*/
|
||||
|
||||
if (!wrapperTemplateChain.IsEmpty)
|
||||
if (!wrapperTemplateChain.IsEmpty && !port)
|
||||
{
|
||||
//WriteQueuedOpenSquirly();
|
||||
str.Append("private const String __cpp_type = \"", GetCursorSpelling!(cursor), "<\"");
|
||||
@@ -1333,21 +1397,32 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
(Self self, bool* firstBase, bool hasVTable) = *(.)client_data;
|
||||
|
||||
Runtime.Assert(Clang.IsVirtualBase(cursor) == 0, "Virtual bases are not supported");
|
||||
//self.WriteQueuedOpenSquirly();
|
||||
if (*firstBase && hasVTable && !HasVTable(Clang.GetCursorDefinition(cursor)))
|
||||
self.str.Append(self.cursorIndent, "private void* cppVtable;\n");
|
||||
self.str.Append(self.cursorIndent);
|
||||
self.AccessSpecifier(cursor);
|
||||
self.str.Append("using ");
|
||||
self.Type(Clang.GetCursorType(cursor));
|
||||
self.str.Append(";\n");
|
||||
if (Clang.IsVirtualBase(cursor) != 0)
|
||||
Internal.FatalError(scope $"Virtual bases are not supported {self.FatalErrorMsg(..scope .(256))}");
|
||||
|
||||
if (self.Flags.HasFlag(.Port))
|
||||
{
|
||||
if (*firstBase) self.str.Append(" : ");
|
||||
else self.str.Append(", ");
|
||||
self.Type(Clang.GetCursorType(cursor));
|
||||
}
|
||||
else
|
||||
{
|
||||
//self.WriteQueuedOpenSquirly();
|
||||
if (*firstBase && hasVTable && !HasVTable(Clang.GetCursorDefinition(cursor)))
|
||||
self.str.Append(self.cursorIndent, "private void* cppVtable;\n");
|
||||
self.str.Append(self.cursorIndent);
|
||||
self.AccessSpecifier(cursor);
|
||||
self.str.Append("using ");
|
||||
self.Type(Clang.GetCursorType(cursor));
|
||||
self.str.Append(";\n");
|
||||
}
|
||||
|
||||
*firstBase = false;
|
||||
return .Continue;
|
||||
}, &(this, &firstBase, hasVTable));
|
||||
|
||||
if (firstBase && hasVTable)
|
||||
if (firstBase && hasVTable && !port)
|
||||
str.Append(cursorIndent, "private void* cppVtable;\n");
|
||||
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
@@ -1362,7 +1437,7 @@ abstract class Cpp2BeefGenerator
|
||||
{
|
||||
case .StructDecl, .ClassDecl: self.str.Append("[CRepr] ");
|
||||
case .UnionDecl: self.str.Append("[CRepr, Union] ");
|
||||
default: Runtime.FatalError("Unhandled record type");
|
||||
default: Internal.FatalError(scope $"Unhandled record type {self.FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
self.AccessSpecifier(cursor);
|
||||
self.str.Append("using ");
|
||||
@@ -1401,7 +1476,8 @@ abstract class Cpp2BeefGenerator
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
Self self = (.)Internal.UnsafeCastToObject(client_data);
|
||||
Runtime.Assert(cursor.kind == .EnumConstantDecl);
|
||||
if (cursor.kind != .EnumConstantDecl)
|
||||
Internal.FatalError(scope $"Unhandled cursor: {cursor.kind} {self.FatalErrorMsg(..scope .(256))}");
|
||||
self.HandleCursor(cursor);
|
||||
return .Continue;
|
||||
}, Internal.UnsafeCastToPtr(this));
|
||||
@@ -1422,10 +1498,10 @@ abstract class Cpp2BeefGenerator
|
||||
CXType type;
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .TypedefDecl: type = Clang.GetTypedefDeclUnderlyingType(cursor);
|
||||
case .TypeAliasDecl: type = Clang.GetCursorType(cursor);
|
||||
case .TypedefDecl, .TypeAliasDecl:
|
||||
type = Clang.GetTypedefDeclUnderlyingType(cursor);
|
||||
default:
|
||||
Runtime.FatalError("Unhandled type alias cursor kind");
|
||||
Internal.FatalError(scope $"Unhandled type alias cursor kind {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
|
||||
if (type.kind == .Pointer) do
|
||||
@@ -1447,7 +1523,8 @@ abstract class Cpp2BeefGenerator
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("typealias");
|
||||
WriteTypeAndName(cursor, type, .TypeAlias);
|
||||
Runtime.Assert(templateParamsWhere.IsEmpty, "type aliases can't have constraints (yet)");
|
||||
if (!templateParamsWhere.IsEmpty)
|
||||
Internal.FatalError(scope $"type aliases can't have constraints (yet) {FatalErrorMsg(..scope .(256))}");
|
||||
}
|
||||
|
||||
protected virtual void MacroDefinition(CXCursor cursor)
|
||||
|
||||
Reference in New Issue
Block a user