Skip to content

Commit 7dd1e00

Browse files
Merge pull request #284 from tannergooding/main
Add support for transparent structs, automatically generating the used attributes/helper types, and to simplify `NativeTypeName` output in a few scenarios
2 parents 2ed374e + 3a5a641 commit 7dd1e00

File tree

12 files changed

+586
-177
lines changed

12 files changed

+586
-177
lines changed

sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.Visit.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal partial interface IOutputBuilder
99
void WriteDivider(bool force = false);
1010
void SuppressDivider();
1111

12-
void WriteCustomAttribute(string attribute);
12+
void WriteCustomAttribute(string attribute, Action callback = null);
1313
void WriteIid(string name, Guid value);
1414
void EmitUsingDirective(string directive);
1515
}

sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace ClangSharp.CSharp
88
internal partial class CSharpOutputBuilder
99
{
1010
private bool _customAttrIsForParameter = false;
11-
public void WriteCustomAttribute(string attribute)
11+
public void WriteCustomAttribute(string attribute, Action callback = null)
1212
{
1313
if (attribute.Equals("Flags") || attribute.Equals("Obsolete"))
1414
{
@@ -18,22 +18,27 @@ public void WriteCustomAttribute(string attribute)
1818
{
1919
AddUsingDirective("System.ComponentModel");
2020
}
21-
else if (attribute.StartsWith("Guid("))
21+
else if (attribute.StartsWith("Guid(") || attribute.StartsWith("Optional, DefaultParameterValue("))
2222
{
2323
AddUsingDirective("System.Runtime.InteropServices");
2424
}
2525

2626
if (!_customAttrIsForParameter)
2727
{
28-
WriteIndented('[');
29-
Write(attribute);
30-
WriteLine(']');
28+
WriteIndentation();
29+
}
30+
31+
Write('[');
32+
Write(attribute);
33+
callback?.Invoke();
34+
Write(']');
35+
36+
if (!_customAttrIsForParameter)
37+
{
38+
WriteNewline();
3139
}
3240
else
3341
{
34-
Write('[');
35-
Write(attribute);
36-
Write(']');
3742
Write(' ');
3843
}
3944
}

sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public void EndField(bool isBodyless = true)
293293

294294
public void BeginFunctionOrDelegate<TCustomAttrGeneratorData>(in FunctionOrDelegateDesc<TCustomAttrGeneratorData> desc, ref bool isMethodClassUnsafe)
295295
{
296-
desc.WriteCustomAttrs(desc.CustomAttrGeneratorData);
296+
desc.WriteCustomAttrs?.Invoke(desc.CustomAttrGeneratorData);
297297

298298
if (desc.IsVirtual)
299299
{
@@ -478,7 +478,7 @@ public void BeginParameter<TCustomAttrGeneratorData>(in ParameterDesc<TCustomAtt
478478
}
479479

480480
_customAttrIsForParameter = true;
481-
info.WriteCustomAttrs(info.CustomAttrGeneratorData);
481+
info.WriteCustomAttrs?.Invoke(info.CustomAttrGeneratorData);
482482
_customAttrIsForParameter = false;
483483
Write(info.Type);
484484
Write(' ');

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Lines changed: 71 additions & 49 deletions
Large diffs are not rendered by default.

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ private void VisitCXXNewExpr(CXXNewExpr cxxNewExpr)
423423
outputBuilder.Write("cxx_new<");
424424

425425

426-
var allocatedTypeName = GetRemappedTypeName(cxxNewExpr, null, cxxNewExpr.AllocatedType, out _, skipUsing: false);
426+
var allocatedTypeName = GetRemappedTypeName(cxxNewExpr, null, cxxNewExpr.AllocatedType, out _);
427427
outputBuilder.Write(allocatedTypeName);
428428

429429
outputBuilder.Write(">(sizeof(");
@@ -544,7 +544,7 @@ private void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr cxxUnres
544544
var outputBuilder = StartCSharpCode();
545545
outputBuilder.Write("new ");
546546

547-
var constructorName = GetRemappedTypeName(cxxUnresolvedConstructExpr, null, cxxUnresolvedConstructExpr.TypeAsWritten, out _, skipUsing: false);
547+
var constructorName = GetRemappedTypeName(cxxUnresolvedConstructExpr, null, cxxUnresolvedConstructExpr.TypeAsWritten, out _);
548548
outputBuilder.Write(constructorName);
549549

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

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

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

589589
if (!_config.DontUseUsingStaticsForEnums)
590590
{
591-
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{enumName}");
591+
if (enumName.StartsWith("__AnonymousEnum_"))
592+
{
593+
if (outputBuilder.Name != _config.MethodClassName)
594+
{
595+
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{_config.MethodClassName}");
596+
}
597+
}
598+
else
599+
{
600+
outputBuilder.AddUsingDirective($"static {_config.Namespace}.{enumName}");
601+
}
592602
}
593603
else
594604
{
@@ -680,13 +690,23 @@ private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr)
680690
if (IsPrevContextDecl<EnumConstantDecl>(out _, out _) && explicitCastExpr.Type is EnumType enumType)
681691
{
682692
outputBuilder.Write('(');
683-
var enumUnderlyingTypeName = GetRemappedTypeName(explicitCastExpr, context: null, enumType.Decl.IntegerType, out _, skipUsing: false);
693+
var enumUnderlyingTypeName = GetRemappedTypeName(explicitCastExpr, context: null, enumType.Decl.IntegerType, out _);
684694
outputBuilder.Write(enumUnderlyingTypeName);
685695
outputBuilder.Write(')');
686696
}
687697

688698
var type = explicitCastExpr.Type;
689-
var typeName = GetRemappedTypeName(explicitCastExpr, context: null, type, out _, skipUsing: false);
699+
var typeName = GetRemappedTypeName(explicitCastExpr, context: null, type, out _);
700+
701+
if (IsPrevContextDecl<VarDecl>(out var varDecl, out _))
702+
{
703+
var cursorName = GetCursorName(varDecl);
704+
705+
if (cursorName.StartsWith("ClangSharpMacro_") && _config.WithTransparentStructs.TryGetValue(typeName, out var transparentValueTypeName))
706+
{
707+
typeName = transparentValueTypeName;
708+
}
709+
}
690710

691711
if (typeName == "IntPtr")
692712
{
@@ -910,7 +930,7 @@ void ForEnumConstantDecl(ImplicitCastExpr implicitCastExpr, EnumConstantDecl enu
910930
{
911931
var type = implicitCastExpr.Type;
912932

913-
var typeName = GetRemappedTypeName(implicitCastExpr, context: null, type, out _, skipUsing: false);
933+
var typeName = GetRemappedTypeName(implicitCastExpr, context: null, type, out _);
914934

915935
outputBuilder.Write('(');
916936
outputBuilder.Write(typeName);
@@ -987,7 +1007,7 @@ long CalculateRootSize(InitListExpr initListExpr, ArrayType arrayType, bool isUn
9871007
void ForArrayType(InitListExpr initListExpr, ArrayType arrayType)
9881008
{
9891009
var type = initListExpr.Type;
990-
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _, skipUsing: false);
1010+
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _);
9911011
var isUnmanagedConstant = false;
9921012
var escapedName = "";
9931013

@@ -1051,7 +1071,7 @@ void ForBuiltinType(InitListExpr initListExpr, BuiltinType builtinType)
10511071
void ForRecordType(InitListExpr initListExpr, RecordType recordType)
10521072
{
10531073
var type = initListExpr.Type;
1054-
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _, skipUsing: false);
1074+
var typeName = GetRemappedTypeName(initListExpr, context: null, type, out _);
10551075
var isUnmanagedConstant = false;
10561076
var escapedName = "";
10571077

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

2227-
22282247
long alignment32 = -1;
22292248
long alignment64 = -1;
22302249

@@ -2310,10 +2329,21 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
23102329
}
23112330

23122331
var needsCast = false;
2313-
var typeName = GetRemappedTypeName(unaryExprOrTypeTraitExpr, context: null, argumentType, out _, skipUsing: false);
2332+
var typeName = GetRemappedTypeName(unaryExprOrTypeTraitExpr, context: null, argumentType, out _);
23142333

23152334
if (parentType != null)
23162335
{
2336+
if ((parentType.Handle.SizeOf == 8) && IsPrevContextDecl<VarDecl>(out var varDecl, out _))
2337+
{
2338+
var cursorName = GetCursorName(varDecl);
2339+
2340+
if (cursorName.StartsWith("ClangSharpMacro_"))
2341+
{
2342+
cursorName = cursorName["ClangSharpMacro_".Length..];
2343+
parentTypeIsVariableSized |= _config.WithTypes.TryGetValue(cursorName, out var remappedTypeName) && ((remappedTypeName == "int") || (remappedTypeName == "uint"));
2344+
}
2345+
}
2346+
23172347
needsCast = parentType.Kind == CXTypeKind.CXType_UInt;
23182348
needsCast |= parentType.Kind == CXTypeKind.CXType_ULong;
23192349
needsCast &= !IsSupportedFixedSizedBufferType(typeName);
@@ -2455,7 +2485,7 @@ private void VisitOffsetOfExpr(OffsetOfExpr offsetOfExpr)
24552485

24562486
outputBuilder.AddUsingDirective("System.Runtime.InteropServices");
24572487
outputBuilder.Write("Marshal.OffsetOf<");
2458-
outputBuilder.Write(GetRemappedTypeName(offsetOfExpr, context: null, offsetOfExpr.TypeSourceInfoType, out var _, skipUsing: false));
2488+
outputBuilder.Write(GetRemappedTypeName(offsetOfExpr, context: null, offsetOfExpr.TypeSourceInfoType, out var _));
24592489
outputBuilder.Write(">(\"");
24602490
Visit(offsetOfExpr.Referenced ?? offsetOfExpr.CursorChildren[1]);
24612491
outputBuilder.Write("\")");

0 commit comments

Comments
 (0)