Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for transparent structs, automatically generating the used attributes/helper types, and to simplify NativeTypeName output in a few scenarios #284

Merged
merged 5 commits into from
Oct 31, 2021
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal partial interface IOutputBuilder
void WriteDivider(bool force = false);
void SuppressDivider();

void WriteCustomAttribute(string attribute);
void WriteCustomAttribute(string attribute, Action callback = null);
void WriteIid(string name, Guid value);
void EmitUsingDirective(string directive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace ClangSharp.CSharp
internal partial class CSharpOutputBuilder
{
private bool _customAttrIsForParameter = false;
public void WriteCustomAttribute(string attribute)
public void WriteCustomAttribute(string attribute, Action callback = null)
{
if (attribute.Equals("Flags") || attribute.Equals("Obsolete"))
{
Expand All @@ -18,22 +18,27 @@ public void WriteCustomAttribute(string attribute)
{
AddUsingDirective("System.ComponentModel");
}
else if (attribute.StartsWith("Guid("))
else if (attribute.StartsWith("Guid(") || attribute.StartsWith("Optional, DefaultParameterValue("))
{
AddUsingDirective("System.Runtime.InteropServices");
}

if (!_customAttrIsForParameter)
{
WriteIndented('[');
Write(attribute);
WriteLine(']');
WriteIndentation();
}

Write('[');
Write(attribute);
callback?.Invoke();
Write(']');

if (!_customAttrIsForParameter)
{
WriteNewline();
}
else
{
Write('[');
Write(attribute);
Write(']');
Write(' ');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public void EndField(bool isBodyless = true)

public void BeginFunctionOrDelegate<TCustomAttrGeneratorData>(in FunctionOrDelegateDesc<TCustomAttrGeneratorData> desc, ref bool isMethodClassUnsafe)
{
desc.WriteCustomAttrs(desc.CustomAttrGeneratorData);
desc.WriteCustomAttrs?.Invoke(desc.CustomAttrGeneratorData);

if (desc.IsVirtual)
{
Expand Down Expand Up @@ -478,7 +478,7 @@ public void BeginParameter<TCustomAttrGeneratorData>(in ParameterDesc<TCustomAtt
}

_customAttrIsForParameter = true;
info.WriteCustomAttrs(info.CustomAttrGeneratorData);
info.WriteCustomAttrs?.Invoke(info.CustomAttrGeneratorData);
_customAttrIsForParameter = false;
Write(info.Type);
Write(' ');
Expand Down
120 changes: 71 additions & 49 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Large diffs are not rendered by default.

54 changes: 42 additions & 12 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ private void VisitCXXNewExpr(CXXNewExpr cxxNewExpr)
outputBuilder.Write("cxx_new<");


var allocatedTypeName = GetRemappedTypeName(cxxNewExpr, null, cxxNewExpr.AllocatedType, out _, skipUsing: false);
var allocatedTypeName = GetRemappedTypeName(cxxNewExpr, null, cxxNewExpr.AllocatedType, out _);
outputBuilder.Write(allocatedTypeName);

outputBuilder.Write(">(sizeof(");
Expand Down Expand Up @@ -544,7 +544,7 @@ private void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr cxxUnres
var outputBuilder = StartCSharpCode();
outputBuilder.Write("new ");

var constructorName = GetRemappedTypeName(cxxUnresolvedConstructExpr, null, cxxUnresolvedConstructExpr.TypeAsWritten, out _, skipUsing: false);
var constructorName = GetRemappedTypeName(cxxUnresolvedConstructExpr, null, cxxUnresolvedConstructExpr.TypeAsWritten, out _);
outputBuilder.Write(constructorName);

outputBuilder.Write('(');
Expand All @@ -571,7 +571,7 @@ private void VisitCXXUuidofExpr(CXXUuidofExpr cxxUuidofExpr)
outputBuilder.Write("typeof(");

var type = cxxUuidofExpr.IsTypeOperand ? cxxUuidofExpr.TypeOperand : cxxUuidofExpr.ExprOperand.Type;
var typeName = GetRemappedTypeName(cxxUuidofExpr, context: null, type, out _, skipUsing: false);
var typeName = GetRemappedTypeName(cxxUuidofExpr, context: null, type, out _);
outputBuilder.Write(typeName);

outputBuilder.Write(").GUID");
Expand All @@ -588,7 +588,17 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr)

if (!_config.DontUseUsingStaticsForEnums)
{
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{enumName}");
if (enumName.StartsWith("__AnonymousEnum_"))
{
if (outputBuilder.Name != _config.MethodClassName)
{
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{_config.MethodClassName}");
}
}
else
{
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{enumName}");
}
}
else
{
Expand Down Expand Up @@ -680,13 +690,23 @@ private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr)
if (IsPrevContextDecl<EnumConstantDecl>(out _, out _) && explicitCastExpr.Type is EnumType enumType)
{
outputBuilder.Write('(');
var enumUnderlyingTypeName = GetRemappedTypeName(explicitCastExpr, context: null, enumType.Decl.IntegerType, out _, skipUsing: false);
var enumUnderlyingTypeName = GetRemappedTypeName(explicitCastExpr, context: null, enumType.Decl.IntegerType, out _);
outputBuilder.Write(enumUnderlyingTypeName);
outputBuilder.Write(')');
}

var type = explicitCastExpr.Type;
var typeName = GetRemappedTypeName(explicitCastExpr, context: null, type, out _, skipUsing: false);
var typeName = GetRemappedTypeName(explicitCastExpr, context: null, type, out _);

if (IsPrevContextDecl<VarDecl>(out var varDecl, out _))
{
var cursorName = GetCursorName(varDecl);

if (cursorName.StartsWith("ClangSharpMacro_") && _config.WithTransparentStructs.TryGetValue(typeName, out var transparentValueTypeName))
{
typeName = transparentValueTypeName;
}
}

if (typeName == "IntPtr")
{
Expand Down Expand Up @@ -910,7 +930,7 @@ void ForEnumConstantDecl(ImplicitCastExpr implicitCastExpr, EnumConstantDecl enu
{
var type = implicitCastExpr.Type;

var typeName = GetRemappedTypeName(implicitCastExpr, context: null, type, out _, skipUsing: false);
var typeName = GetRemappedTypeName(implicitCastExpr, context: null, type, out _);

outputBuilder.Write('(');
outputBuilder.Write(typeName);
Expand Down Expand Up @@ -987,7 +1007,7 @@ long CalculateRootSize(InitListExpr initListExpr, ArrayType arrayType, bool isUn
void ForArrayType(InitListExpr initListExpr, ArrayType arrayType)
{
var type = initListExpr.Type;
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _, skipUsing: false);
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _);
var isUnmanagedConstant = false;
var escapedName = "";

Expand Down Expand Up @@ -1051,7 +1071,7 @@ void ForBuiltinType(InitListExpr initListExpr, BuiltinType builtinType)
void ForRecordType(InitListExpr initListExpr, RecordType recordType)
{
var type = initListExpr.Type;
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _, skipUsing: false);
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _);
var isUnmanagedConstant = false;
var escapedName = "";

Expand Down Expand Up @@ -2224,7 +2244,6 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
var outputBuilder = StartCSharpCode();
var argumentType = unaryExprOrTypeTraitExpr.TypeOfArgument;


long alignment32 = -1;
long alignment64 = -1;

Expand Down Expand Up @@ -2310,10 +2329,21 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
}

var needsCast = false;
var typeName = GetRemappedTypeName(unaryExprOrTypeTraitExpr, context: null, argumentType, out _, skipUsing: false);
var typeName = GetRemappedTypeName(unaryExprOrTypeTraitExpr, context: null, argumentType, out _);

if (parentType != null)
{
if ((parentType.Handle.SizeOf == 8) && IsPrevContextDecl<VarDecl>(out var varDecl, out _))
{
var cursorName = GetCursorName(varDecl);

if (cursorName.StartsWith("ClangSharpMacro_"))
{
cursorName = cursorName["ClangSharpMacro_".Length..];
parentTypeIsVariableSized |= _config.WithTypes.TryGetValue(cursorName, out var remappedTypeName) && ((remappedTypeName == "int") || (remappedTypeName == "uint"));
}
}

needsCast = parentType.Kind == CXTypeKind.CXType_UInt;
needsCast |= parentType.Kind == CXTypeKind.CXType_ULong;
needsCast &= !IsSupportedFixedSizedBufferType(typeName);
Expand Down Expand Up @@ -2455,7 +2485,7 @@ private void VisitOffsetOfExpr(OffsetOfExpr offsetOfExpr)

outputBuilder.AddUsingDirective("System.Runtime.InteropServices");
outputBuilder.Write("Marshal.OffsetOf<");
outputBuilder.Write(GetRemappedTypeName(offsetOfExpr, context: null, offsetOfExpr.TypeSourceInfoType, out var _, skipUsing: false));
outputBuilder.Write(GetRemappedTypeName(offsetOfExpr, context: null, offsetOfExpr.TypeSourceInfoType, out var _));
outputBuilder.Write(">(\"");
Visit(offsetOfExpr.Referenced ?? offsetOfExpr.CursorChildren[1]);
outputBuilder.Write("\")");
Expand Down
Loading