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

Merging various fixes and improvements #269

Merged
merged 16 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
05db205
Configure ClangSharp for 12.0.0 release
tannergooding Aug 19, 2021
eda14e3
Ensure we look through parens when handling sizeof exprs
tannergooding Sep 4, 2021
add4118
Ensure that string and character literals don't unecessarily escape
tannergooding Sep 5, 2021
4bb64fb
Merge remote-tracking branch 'msft/main' into release/v12.0.0
tannergooding Sep 5, 2021
b57bb4d
Ensure that implicit casts of enums to integers have explicit casts g…
tannergooding Sep 5, 2021
30a452f
Ensure we insert `unchecked` for logical not operations that deal wit…
tannergooding Sep 5, 2021
cca86dc
Ensure unsupported default parameter values are partially handled.
tannergooding Sep 5, 2021
83cb797
Ensure ascii character literals are cast to sbyte
tannergooding Sep 5, 2021
fb55a3a
Ensure that IntPtr and UIntPtr are properly handled when checking for…
tannergooding Sep 6, 2021
b76c30d
Ensure a paren is inserted for implicit bool conversions involving bi…
tannergooding Sep 6, 2021
6f38079
Ensure we don't print a warning for pointer parameter defaults that a…
tannergooding Sep 6, 2021
316f4c2
Better handle checking for overflow on binary operators
tannergooding Sep 6, 2021
a811b1f
Use nint/nuint in casts for more efficient codegen
tannergooding Sep 6, 2021
4ce1bc0
Ensure negative literals aren't treated as native integer constants
tannergooding Sep 6, 2021
6a55a5b
Update Directory.Build.props
tannergooding Sep 22, 2021
f9c3c09
Fixing some tests and simplify when casts are inserted for character …
tannergooding Sep 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<PackageOutputPath>$(BaseArtifactsPath)pkg/$(Configuration)/</PackageOutputPath>
<Product>ClangSharp</Product>
<VersionPrefix>12.0.0</VersionPrefix>
<VersionSuffix>beta2</VersionSuffix>
<VersionSuffix>beta3</VersionSuffix>
<VersionSuffix Condition="'$(BUILD_REASON)' == 'PullRequest'">pr</VersionSuffix>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</PropertyGroup>

<!-- Settings that allow testing and packing to work by default -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == '' AND '$(Contin)' != 'true'">
<PropertyGroup Condition="'$(RuntimeIdentifier)' == ''">
<RuntimeIdentifier>$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
<RuntimeIdentifier Condition="'$(OVERRIDE_RUNTIME_IDENTIFIER)' != ''">$(OVERRIDE_RUNTIME_IDENTIFIER)</RuntimeIdentifier>
</PropertyGroup>
Expand Down
8 changes: 8 additions & 0 deletions scripts/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ jobs:
architecture: x64
testwin32metadata: false

- template: azure-windows.yml
parameters:
name: windows_release_x64
pool: windows-latest
configuration: Release
architecture: x64
testwin32metadata: false

- template: azure-windows.yml
parameters:
name: test_win32metadata
Expand Down
73 changes: 52 additions & 21 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,27 @@ void ForFunctionDecl(ParmVarDecl parmVarDecl, FunctionDecl functionDecl)
if (parmVarDecl.HasDefaultArg)
{
_outputBuilder.BeginParameterDefault();
UncheckStmt(typeName, parmVarDecl.DefaultArg);

var defaultArg = parmVarDecl.DefaultArg;

if (parmVarDecl.Type.CanonicalType.IsPointerType && (defaultArg.Handle.Evaluate.Kind == CXEvalResultKind.CXEval_UnExposed))
{
if (!IsStmtAsWritten<CXXNullPtrLiteralExpr>(defaultArg, out _, removeParens: true) &&
(!IsStmtAsWritten<CastExpr>(defaultArg, out var castExpr, removeParens: true) || (castExpr.CastKind != CX_CastKind.CX_CK_NullToPointer)) &&
(!IsStmtAsWritten<IntegerLiteral>(defaultArg, out var integerLiteral, removeParens: true) || (integerLiteral.Value != 0)))
{
AddDiagnostic(DiagnosticLevel.Info, $"Unsupported default parameter: '{name}'. Generated bindings may be incomplete.", defaultArg);
}

var outputBuilder = StartCSharpCode();
outputBuilder.Write("null");
StopCSharpCode();
}
else
{
UncheckStmt(typeName, parmVarDecl.DefaultArg);
}

_outputBuilder.EndParameterDefault();
}

Expand Down Expand Up @@ -2521,12 +2541,12 @@ void ForUnderlyingType(TypedefDecl typedefDecl, Type underlyingType)
if (_config.LogPotentialTypedefRemappings)
{
var typedefName = typedefDecl.UnderlyingDecl.Name;
var possibleNamesToRemap = new string[] {"_" + typedefName, "_tag" + typedefName, "tag" + typedefName};
var possibleNamesToRemap = new string[] {"_" + typedefName, "_tag" + typedefName, "tag" + typedefName, typedefName + "_tag" };
var underlyingName = underlyingTagType.AsString;

foreach (var possibleNameToRemap in possibleNamesToRemap)
{
if (!_config.RemappedNames.ContainsKey(possibleNameToRemap))
if (!_config.RemappedNames.ContainsKey(possibleNameToRemap) && !_config.RemappedNames.ContainsKey(possibleNameToRemap + "*"))
{
if (possibleNameToRemap == underlyingName)
{
Expand Down Expand Up @@ -2704,7 +2724,7 @@ private void VisitVarDecl(VarDecl varDecl)
}
}
}
else if ((type.IsLocalConstQualified || isMacroDefinitionRecord) && CanBeConstant(type, varDecl.Init))
else if ((type.IsLocalConstQualified || isMacroDefinitionRecord) && CanBeConstant(type, typeName, varDecl.Init))
{
kind |= ConstantKind.PrimitiveConstant;
}
Expand Down Expand Up @@ -2820,15 +2840,15 @@ void ForDeclStmt(VarDecl varDecl, DeclStmt declStmt)
StopCSharpCode();
}

bool CanBeConstant(Type type, Expr initExpr)
bool CanBeConstant(Type type, string targetTypeName, Expr initExpr)
{
if (type is AttributedType attributedType)
{
return CanBeConstant(attributedType.ModifiedType, initExpr);
return CanBeConstant(attributedType.ModifiedType, targetTypeName, initExpr);
}
else if (type is AutoType autoType)
{
return CanBeConstant(autoType.CanonicalType, initExpr);
return CanBeConstant(autoType.CanonicalType, targetTypeName, initExpr);
}
else if (type is BuiltinType builtinType)
{
Expand All @@ -2852,28 +2872,28 @@ bool CanBeConstant(Type type, Expr initExpr)
case CXTypeKind.CXType_Float:
case CXTypeKind.CXType_Double:
{
return IsConstant(initExpr);
return IsConstant(targetTypeName, initExpr);
}
}
}
else if (type is ElaboratedType elaboratedType)
{
return CanBeConstant(elaboratedType.NamedType, initExpr);
return CanBeConstant(elaboratedType.NamedType, targetTypeName, initExpr);
}
else if (type is EnumType enumType)
{
return CanBeConstant(enumType.Decl.IntegerType, initExpr);
return CanBeConstant(enumType.Decl.IntegerType, targetTypeName, initExpr);
}
else if (type is TypedefType typedefType)
{
return CanBeConstant(typedefType.Decl.UnderlyingType, initExpr);
return CanBeConstant(typedefType.Decl.UnderlyingType, targetTypeName, initExpr);
}

return false;
}
}

private bool IsConstant(Expr initExpr)
private bool IsConstant(string targetTypeName, Expr initExpr)
{
switch (initExpr.StmtClass)
{
Expand All @@ -2882,7 +2902,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_ConditionalOperator:
{
var conditionalOperator = (ConditionalOperator)initExpr;
return IsConstant(conditionalOperator.Cond) && IsConstant(conditionalOperator.LHS) && IsConstant(conditionalOperator.RHS);
return IsConstant(targetTypeName, conditionalOperator.Cond) && IsConstant(targetTypeName, conditionalOperator.LHS) && IsConstant(targetTypeName, conditionalOperator.RHS);
}

// case CX_StmtClass.CX_StmtClass_AddrLabelExpr:
Expand All @@ -2901,7 +2921,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_BinaryOperator:
{
var binaryOperator = (BinaryOperator)initExpr;
return IsConstant(binaryOperator.LHS) && IsConstant(binaryOperator.RHS);
return IsConstant(targetTypeName, binaryOperator.LHS) && IsConstant(targetTypeName, binaryOperator.RHS);
}

// case CX_StmtClass.CX_StmtClass_CompoundAssignOperator:
Expand Down Expand Up @@ -2982,7 +3002,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_CXXFunctionalCastExpr:
{
var cxxFunctionalCastExpr = (ExplicitCastExpr)initExpr;
return IsConstant(cxxFunctionalCastExpr.SubExprAsWritten);
return IsConstant(targetTypeName, cxxFunctionalCastExpr.SubExprAsWritten);
}

// case CX_StmtClass.CX_StmtClass_CXXConstCastExpr:
Expand All @@ -2993,7 +3013,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_ImplicitCastExpr:
{
var implicitCastExpr = (ImplicitCastExpr)initExpr;
return IsConstant(implicitCastExpr.SubExprAsWritten);
return IsConstant(targetTypeName, implicitCastExpr.SubExprAsWritten);
}

case CX_StmtClass.CX_StmtClass_CharacterLiteral:
Expand All @@ -3012,7 +3032,7 @@ private bool IsConstant(Expr initExpr)
{
var declRefExpr = (DeclRefExpr)initExpr;
return (declRefExpr.Decl is EnumConstantDecl) ||
((declRefExpr.Decl is VarDecl varDecl) && varDecl.HasInit && IsConstant(varDecl.Init));
((declRefExpr.Decl is VarDecl varDecl) && varDecl.HasInit && IsConstant(targetTypeName, varDecl.Init));
}

// case CX_StmtClass.CX_StmtClass_DependentCoawaitExpr:
Expand All @@ -3033,7 +3053,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_ExprWithCleanups:
{
var exprWithCleanups = (ExprWithCleanups)initExpr;
return IsConstant(exprWithCleanups.SubExpr);
return IsConstant(targetTypeName, exprWithCleanups.SubExpr);
}

// case CX_StmtClass.CX_StmtClass_FunctionParmPackExpr:
Expand Down Expand Up @@ -3089,7 +3109,7 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_ParenExpr:
{
var parenExpr = (ParenExpr)initExpr;
return IsConstant(parenExpr.SubExpr);
return IsConstant(targetTypeName, parenExpr.SubExpr);
}

case CX_StmtClass.CX_StmtClass_ParenListExpr:
Expand All @@ -3098,7 +3118,7 @@ private bool IsConstant(Expr initExpr)

foreach (var expr in parenListExpr.Exprs)
{
if (IsConstant(expr))
if (IsConstant(targetTypeName, expr))
{
return true;
}
Expand Down Expand Up @@ -3159,7 +3179,18 @@ private bool IsConstant(Expr initExpr)
case CX_StmtClass.CX_StmtClass_UnaryOperator:
{
var unaryOperator = (UnaryOperator)initExpr;
return IsConstant(unaryOperator.SubExpr);

if (!IsConstant(targetTypeName, unaryOperator.SubExpr))
{
return false;
}

if (unaryOperator.Opcode != CX_UnaryOperatorKind.CX_UO_Minus)
{
return true;
}

return targetTypeName is not "IntPtr" and not "nint" and not "nuint" and not "UIntPtr";
}

// case CX_StmtClass.CX_StmtClass_VAArgExpr:
Expand Down
55 changes: 47 additions & 8 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,38 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral)
}
else
{
var isPreviousExplicitCast = IsPrevContextStmt<ExplicitCastExpr>(out _);
var castType = "";

if (!isPreviousExplicitCast)
if (IsPrevContextStmt<ImplicitCastExpr>(out var implicitCastExpr))
{
outputBuilder.Write("(byte)(");
// C# characters are effectively `ushort` while C defaults to "char" which is
// most typically `sbyte`. Due to this we need to insert a correct implicit
// cast to ensure things are correctly handled here.

var castExprTypeName = GetRemappedTypeName(implicitCastExpr, context: null, implicitCastExpr.Type, out _, skipUsing: true);

if (!IsUnsigned(castExprTypeName))
{
castType = "sbyte";
}
else if (implicitCastExpr.Type.Handle.NumBits < 16)
{
// Cast to byte if the target type is less

castType = "byte";
}
}

if (castType != "")
{
outputBuilder.Write("(sbyte)(");
}

outputBuilder.Write('\'');
outputBuilder.Write(EscapeCharacter((char)characterLiteral.Value));
outputBuilder.Write('\'');

if (!isPreviousExplicitCast)
if (castType != "")
{
outputBuilder.Write(')');
}
Expand Down Expand Up @@ -634,6 +654,7 @@ private void VisitDoStmt(DoStmt doStmt)
private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr)
{
var outputBuilder = StartCSharpCode();

if (IsPrevContextDecl<EnumConstantDecl>(out _) && explicitCastExpr.Type is EnumType enumType)
{
outputBuilder.Write('(');
Expand All @@ -643,10 +664,17 @@ private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr)
}

var type = explicitCastExpr.Type;


var typeName = GetRemappedTypeName(explicitCastExpr, context: null, type, out _);

if (typeName == "IntPtr")
{
typeName = "nint";
}
else if (typeName == "UIntPtr")
{
typeName = "nuint";
}

outputBuilder.Write('(');
outputBuilder.Write(typeName);
outputBuilder.Write(')');
Expand Down Expand Up @@ -832,7 +860,7 @@ private void VisitImplicitCastExpr(ImplicitCastExpr implicitCastExpr)

default:
{
if ((subExpr is DeclRefExpr declRefExpr) && (declRefExpr.Decl is EnumConstantDecl enumConstantDecl))
if (IsStmtAsWritten<DeclRefExpr>(subExpr, out var declRefExpr, removeParens: true) && (declRefExpr.Decl is EnumConstantDecl enumConstantDecl))
{
ForEnumConstantDecl(implicitCastExpr, enumConstantDecl);
}
Expand Down Expand Up @@ -1901,7 +1929,7 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
{
var arg = args[i];

if (IsStmtAsWritten(arg, unaryExprOrTypeTraitExpr))
if (IsStmtAsWritten(arg, unaryExprOrTypeTraitExpr, removeParens: true))
{
index = i;
break;
Expand Down Expand Up @@ -2026,7 +2054,18 @@ private void VisitUnaryOperator(UnaryOperator unaryOperator)

if (canonicalType.IsIntegerType && (canonicalType.Kind != CXTypeKind.CXType_Bool))
{
var needsParens = IsStmtAsWritten<BinaryOperator>(subExpr, out _);

if (needsParens)
{
outputBuilder.Write('(');
}
Visit(subExpr);

if (needsParens)
{
outputBuilder.Write(')');
}
outputBuilder.Write(" == 0");
}
else if (canonicalType is PointerType or ReferenceType)
Expand Down
Loading