Browse Source

Fix default arguments to only map to null if pointers

This bug is revealed by properly fixing the reading of ABI parameters in the parser.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1213/head
Dimitar Dobrev 6 years ago
parent
commit
1fc1b4ec51
  1. 14
      src/AST/FunctionExtensions.cs
  2. 16
      src/CppParser/Parser.cpp
  3. 5
      src/Generator/Driver.cs
  4. 6
      src/Generator/Generators/CSharp/CSharpGenerator.cs
  5. 2
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  6. 2
      tests/CSharp/CSharp.Tests.cs
  7. 10
      tests/CSharp/CSharp.cpp
  8. 3
      tests/CSharp/CSharp.h

14
src/AST/FunctionExtensions.cs

@ -16,18 +16,8 @@ namespace CppSharp.AST
var pointer = new QualifiedType(new PointerType(new QualifiedType(new BuiltinType(PrimitiveType.Void)))); var pointer = new QualifiedType(new PointerType(new QualifiedType(new BuiltinType(PrimitiveType.Void))));
if (isInstanceMethod && !isItaniumLikeAbi) if (isInstanceMethod &&
{ (!isItaniumLikeAbi || !function.HasIndirectReturnTypeParameter))
@params.Add(new Parameter
{
QualifiedType = pointer,
Name = "__instance",
Namespace = function
});
}
if (!function.HasIndirectReturnTypeParameter &&
isInstanceMethod && isItaniumLikeAbi)
{ {
@params.Add(new Parameter @params.Add(new Parameter
{ {

16
src/CppParser/Parser.cpp

@ -2923,14 +2923,9 @@ Enumeration::Item* Parser::WalkEnumItem(clang::EnumConstantDecl* ECD)
static const clang::CodeGen::CGFunctionInfo& GetCodeGenFunctionInfo( static const clang::CodeGen::CGFunctionInfo& GetCodeGenFunctionInfo(
clang::CodeGen::CodeGenTypes* CodeGenTypes, const clang::FunctionDecl* FD) clang::CodeGen::CodeGenTypes* CodeGenTypes, const clang::FunctionDecl* FD)
{ {
using namespace clang; auto FTy = FD->getType()->getCanonicalTypeUnqualified();
if (auto CD = dyn_cast<clang::CXXConstructorDecl>(FD)) { return CodeGenTypes->arrangeFreeFunctionType(
return CodeGenTypes->arrangeCXXStructorDeclaration(CD); FTy.castAs<clang::FunctionProtoType>());
} else if (auto DD = dyn_cast<clang::CXXDestructorDecl>(FD)) {
return CodeGenTypes->arrangeCXXStructorDeclaration(DD);
}
return CodeGenTypes->arrangeFunctionDeclaration(FD);
} }
bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty) bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
@ -3294,9 +3289,8 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
unsigned Index = 0; unsigned Index = 0;
for (const auto& Arg : CGInfo.arguments()) for (const auto& Arg : CGInfo.arguments())
{ {
if (Index >= F->Parameters.size()) F->Parameters[Index++]->isIndirect =
continue; Arg.info.isIndirect() && !Arg.info.getIndirectByVal();
F->Parameters[Index++]->isIndirect = Arg.info.isIndirect();
} }
MarkValidity(F); MarkValidity(F);

5
src/Generator/Driver.cs

@ -253,11 +253,6 @@ namespace CppSharp
if (Options.IsCSharpGenerator) if (Options.IsCSharpGenerator)
{ {
if (Options.GenerateDefaultValuesForArguments)
{
TranslationUnitPasses.AddPass(new FixDefaultParamValuesOfOverridesPass());
TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass());
}
TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass()); TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass());
TranslationUnitPasses.AddPass(new MultipleInheritancePass()); TranslationUnitPasses.AddPass(new MultipleInheritancePass());
} }

6
src/Generator/Generators/CSharp/CSharpGenerator.cs

@ -25,6 +25,12 @@ namespace CppSharp.Generators.CSharp
public override bool SetupPasses() public override bool SetupPasses()
{ {
if (Context.Options.GenerateDefaultValuesForArguments)
{
Context.TranslationUnitPasses.AddPass(new FixDefaultParamValuesOfOverridesPass());
Context.TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass());
}
// Both the CheckOperatorsOverloadsPass and CheckAbiParameters can // Both the CheckOperatorsOverloadsPass and CheckAbiParameters can
// create and and new parameters to functions and methods. Make sure // create and and new parameters to functions and methods. Make sure
// CheckAbiParameters runs last because hidden structure parameters // CheckAbiParameters runs last because hidden structure parameters

2
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -75,7 +75,7 @@ namespace CppSharp.Passes
{ {
var desugared = type.Desugar(); var desugared = type.Desugar();
if (!desugared.IsPrimitiveTypeConvertibleToRef() && if (desugared.IsAddress() && !desugared.IsPrimitiveTypeConvertibleToRef() &&
(expression.String == "0" || expression.String == "nullptr")) (expression.String == "0" || expression.String == "nullptr"))
{ {
result = desugared.GetPointee()?.Desugar() is FunctionType ? result = desugared.GetPointee()?.Desugar() is FunctionType ?

2
tests/CSharp/CSharp.Tests.cs

@ -249,7 +249,7 @@ public unsafe class CSharpTests : GeneratorTestFixture
methodsWithDefaultValues.DefaultMappedToZeroEnum(); methodsWithDefaultValues.DefaultMappedToZeroEnum();
methodsWithDefaultValues.DefaultMappedToEnumAssignedWithCtor(); methodsWithDefaultValues.DefaultMappedToEnumAssignedWithCtor();
methodsWithDefaultValues.DefaultZeroMappedToEnumAssignedWithCtor(); methodsWithDefaultValues.DefaultZeroMappedToEnumAssignedWithCtor();
methodsWithDefaultValues.DefaultImplicitCtorInt(); Assert.That(methodsWithDefaultValues.DefaultImplicitCtorInt().Priv, Is.EqualTo(0));
methodsWithDefaultValues.DefaultImplicitCtorChar(); methodsWithDefaultValues.DefaultImplicitCtorChar();
methodsWithDefaultValues.DefaultImplicitCtorFoo(); methodsWithDefaultValues.DefaultImplicitCtorFoo();
methodsWithDefaultValues.DefaultImplicitCtorEnum(); methodsWithDefaultValues.DefaultImplicitCtorEnum();

10
tests/CSharp/CSharp.cpp

@ -117,7 +117,7 @@ Quux::Quux() : _setterWithDefaultOverload(0)
Quux::Quux(int i) : Quux() Quux::Quux(int i) : Quux()
{ {
priv = i;
} }
Quux::Quux(char c) : Quux() Quux::Quux(char c) : Quux()
@ -139,6 +139,11 @@ Quux::~Quux()
} }
} }
int Quux::getPriv() const
{
return priv;
}
Foo* Quux::setterWithDefaultOverload() Foo* Quux::setterWithDefaultOverload()
{ {
return _setterWithDefaultOverload; return _setterWithDefaultOverload;
@ -645,8 +650,9 @@ void MethodsWithDefaultValues::defaultZeroMappedToEnumAssignedWithCtor(DefaultZe
{ {
} }
void MethodsWithDefaultValues::defaultImplicitCtorInt(Quux arg) Quux MethodsWithDefaultValues::defaultImplicitCtorInt(Quux arg)
{ {
return arg;
} }
void MethodsWithDefaultValues::defaultImplicitCtorChar(Quux arg) void MethodsWithDefaultValues::defaultImplicitCtorChar(Quux arg)

3
tests/CSharp/CSharp.h

@ -56,6 +56,7 @@ public:
Quux(Foo f); Quux(Foo f);
~Quux(); ~Quux();
int getPriv() const;
Foo* setterWithDefaultOverload(); Foo* setterWithDefaultOverload();
void setSetterWithDefaultOverload(Foo* value = new Foo()); void setSetterWithDefaultOverload(Foo* value = new Foo());
@ -419,7 +420,7 @@ public:
void defaultMappedToZeroEnum(QFlags<Flags> qFlags = 0); void defaultMappedToZeroEnum(QFlags<Flags> qFlags = 0);
void defaultMappedToEnumAssignedWithCtor(QFlags<Flags> qFlags = QFlags<Flags>()); void defaultMappedToEnumAssignedWithCtor(QFlags<Flags> qFlags = QFlags<Flags>());
void defaultZeroMappedToEnumAssignedWithCtor(DefaultZeroMappedToEnum defaultZeroMappedToEnum = DefaultZeroMappedToEnum()); void defaultZeroMappedToEnumAssignedWithCtor(DefaultZeroMappedToEnum defaultZeroMappedToEnum = DefaultZeroMappedToEnum());
void defaultImplicitCtorInt(Quux arg = 0); Quux defaultImplicitCtorInt(Quux arg = 0);
void defaultImplicitCtorChar(Quux arg = 'a'); void defaultImplicitCtorChar(Quux arg = 'a');
void defaultImplicitCtorFoo(Quux arg = Foo()); void defaultImplicitCtorFoo(Quux arg = Foo());
// this looks the same test as 'defaultRefTypeEnumImplicitCtor' two lines below // this looks the same test as 'defaultRefTypeEnumImplicitCtor' two lines below

Loading…
Cancel
Save