@ -28,7 +28,7 @@ namespace CppSharp.Passes
@@ -28,7 +28,7 @@ namespace CppSharp.Passes
if ( CheckForDefaultPointer ( desugared , parameter ) )
continue ;
bool? defaultConstruct = CheckForDefaultConstruct ( desugared , parameter ) ;
bool? defaultConstruct = CheckForDefaultConstruct ( desugared , parameter . DefaultArgument ) ;
if ( defaultConstruct = = null | |
( ! Driver . Options . MarshalCharAsManagedChar & &
parameter . Type . Desugar ( ) . IsPrimitiveType ( PrimitiveType . UChar ) ) )
@ -39,10 +39,13 @@ namespace CppSharp.Passes
@@ -39,10 +39,13 @@ namespace CppSharp.Passes
if ( defaultConstruct = = true )
continue ;
if ( CheckForEnumValue ( parameter , desugared ) )
if ( CheckForEnumValue ( parameter . DefaultArgument , desugared ) )
continue ;
CheckForAnonExpression ( desugared , parameter ) ;
CheckForDefaultEmptyChar ( parameter , desugared ) ;
}
GenerateOverloads ( function , overloadIndices ) ;
@ -50,6 +53,21 @@ namespace CppSharp.Passes
@@ -50,6 +53,21 @@ namespace CppSharp.Passes
return result ;
}
private bool CheckForAnonExpression ( Type desugared , Parameter parameter )
{
var cast = parameter . DefaultArgument as CastExpr ;
if ( cast ! = null )
{
if ( cast . SubExpression is BuiltinTypeExpression )
{
// The output string is correct in the deepest expression. Copy it to the outernmost.
cast . String = cast . SubExpression . String ;
return true ;
}
}
return true ;
}
private static bool CheckForDefaultPointer ( Type desugared , Parameter parameter )
{
if ( desugared . IsPointer ( ) )
@ -62,20 +80,42 @@ namespace CppSharp.Passes
@@ -62,20 +80,42 @@ namespace CppSharp.Passes
return false ;
}
private bool? CheckForDefaultConstruct ( Type desugared , Parameter parameter )
private bool? CheckForDefaultConstruct ( Type desugared , Expression arg )
{
Method ctor = parameter . DefaultArgument . Declaration as Method ;
// Unwrapping the constructor and a possible cast
Method ctor = null ;
CastExpr castExpression = null ;
CtorExpr ctorExpression = null ;
if ( arg is CtorExpr )
{
ctorExpression = ( CtorExpr ) arg ;
ctor = ( Method ) ctorExpression . Declaration ;
}
else if ( arg is CastExpr & & ( ( CastExpr ) arg ) . SubExpression is CtorExpr )
{
castExpression = ( CastExpr ) arg ;
ctorExpression = ( CtorExpr ) castExpression . SubExpression ;
ctor = ( Method ) ctorExpression . Declaration ;
}
else
{
return false ;
}
var innerArg = ctorExpression . SubExpression ;
if ( ctor = = null | | ! ctor . IsConstructor )
return false ;
// Unwrapping the underlying type behind a possible pointer/reference
Type type ;
desugared . IsPointerTo ( out type ) ;
type = type ? ? desugared ;
Class decl ;
if ( ! type . TryGetClass ( out decl ) )
return false ;
TypeMap typeMap ;
TypeMap typeMap ;
if ( Driver . TypeDatabase . FindTypeMap ( decl , type , out typeMap ) )
{
Type typeInSignature ;
@ -102,43 +142,79 @@ namespace CppSharp.Passes
@@ -102,43 +142,79 @@ namespace CppSharp.Passes
Enumeration @enum ;
if ( typeInSignature . TryGetEnum ( out @enum ) )
{
return true ;
var argCast = ( CastExpr ) arg ;
Expression literal = ( ( CtorExpr ) argCast . SubExpression ) . SubExpression ;
if ( CheckForEnumValue ( literal , desugared ) )
{
argCast . String = literal . String ;
argCast . SubExpression . String = literal . String ;
return true ;
}
else
{
return false ;
}
}
if ( mappedTo = = "string" & & ctor . Parameters . Count = = 0 )
{
parameter . DefaultArgument . String = "\"\"" ;
arg . String = "\"\"" ;
return true ;
}
}
parameter . DefaultArgument . String = string . Format ( "new {0}" , parameter . DefaultArgument . String ) ;
if ( ctor . Parameters . Count > 0 & & ctor . Parameters [ 0 ] . OriginalName = = "_0" )
parameter . DefaultArgument . String = parameter . DefaultArgument . String . Replace ( "(0)" , "()" ) ;
if ( innerArg is CtorExpr | | innerArg is CastExpr )
{
Type innerDesugared = ctor . Parameters [ 0 ] . Type . Desugar ( ) ;
CheckForDefaultConstruct ( innerDesugared , innerArg ) ;
if ( innerDesugared . IsPointer ( ) & & innerArg . String = = "0" )
innerArg . String = "" ;
arg . String = string . Format ( "new {0}({1})" , ctor . Name , innerArg . String ) ;
}
else if ( innerArg ! = null )
{
Type innerDesugared = ctor . Parameters [ 0 ] . Type . Desugar ( ) ;
CheckForEnumValue ( innerArg , innerDesugared ) ;
arg . String = string . Format ( "new {0}({1})" , ctor . Name , innerArg . String ) ;
}
else
{
arg . String = string . Format ( "new {0}()" , ctor . Name ) ;
}
return decl . IsValueType ? true : ( bool? ) null ;
}
private static bool CheckForEnumValue ( Parameter parameter , Type desugared )
private static bool CheckForEnumValue ( Expression arg , Type desugared )
{
var enumItem = parameter . DefaultArgument . Declaration as Enumeration . Item ;
// Handle a simple cast (between int and enum, for example)
var argCast = arg as CastExpr ;
Expression literal ;
if ( argCast ! = null )
literal = argCast . SubExpression ;
else
literal = arg ;
// The default case
var enumItem = literal . Declaration as Enumeration . Item ;
if ( enumItem ! = null )
{
parameter . DefaultArgument . String = string . Format ( "{0}{1}{2}.{3}" ,
arg . String = string . Format ( "{0}{1}{2}.{3}" ,
desugared . IsPrimitiveType ( ) ? "(int) " : string . Empty ,
string . IsNullOrEmpty ( enumItem . Namespace . Namespace . Name )
? string . Empty
: enumItem . Namespace . Namespace . Name + "." , enumItem . Namespace . Name , enumItem . Name ) ;
return true ;
}
var call = p arameter . DefaultAr gument . Declaration as Function ;
if ( call ! = null | | parameter . DefaultArgument . Class = = StatementClass . BinaryOperator )
// Handle cases like "Flags::Flag1 | Flags::Flag2"
var call = arg . Declaration as Function ;
if ( ( call ! = null & & call . ReturnType . Type . IsEnum ( ) ) | | arg . Class = = StatementClass . BinaryOperator )
{
string @params = regexFunctionParams . Match ( p arameter . DefaultAr gument . String ) . Groups [ 1 ] . Value ;
string @params = regexFunctionParams . Match ( arg . String ) . Groups [ 1 ] . Value ;
if ( @params . Contains ( "::" ) )
p arameter . DefaultAr gument . String = regexDoubleColon . Replace ( @params , desugared + "." ) ;
arg . String = regexDoubleColon . Replace ( @params , desugared + "." ) ;
else
p arameter . DefaultAr gument . String = regexName . Replace ( @params , desugared + ".$1" ) ;
arg . String = regexName . Replace ( @params , desugared + ".$1" ) ;
return true ;
}
return false ;