Skip to content

Commit

Permalink
Merge pull request #269 from microsoft/release/v12.0.0
Browse files Browse the repository at this point in the history
Merging various fixes and improvements
  • Loading branch information
tannergooding authored Sep 24, 2021
2 parents 84e5f96 + f9c3c09 commit 83d82f0
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 49 deletions.
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

0 comments on commit 83d82f0

Please sign in to comment.