Browse Source

Converted to 0 default expressions calling an empty ctor of a type mapped to an enum.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/503/merge
Dimitar Dobrev 10 years ago
parent
commit
56b02cfcf9
  1. 16
      src/CppParser/Parser.cpp
  2. 63
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  3. 1
      tests/CSharpTemp/CSharpTemp.Tests.cs
  4. 20
      tests/CSharpTemp/CSharpTemp.cpp
  5. 24
      tests/CSharpTemp/CSharpTemp.h

16
src/CppParser/Parser.cpp

@ -2281,10 +2281,11 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
P->HasDefaultValue = VD->hasDefaultArg(); P->HasDefaultValue = VD->hasDefaultArg();
P->_Namespace = NS; P->_Namespace = NS;
P->Index = VD->getFunctionScopeIndex(); P->Index = VD->getFunctionScopeIndex();
if (VD->hasDefaultArg() && !VD->hasUnparsedDefaultArg() && !VD->hasUninstantiatedDefaultArg()) if (VD->hasDefaultArg() && !VD->hasUnparsedDefaultArg())
{ if (VD->hasUninstantiatedDefaultArg())
P->DefaultArgument = WalkExpression(VD->getUninstantiatedDefaultArg());
else
P->DefaultArgument = WalkExpression(VD->getDefaultArg()); P->DefaultArgument = WalkExpression(VD->getDefaultArg());
}
HandleDeclaration(VD, P); HandleDeclaration(VD, P);
F->Parameters.push_back(P); F->Parameters.push_back(P);
@ -2630,9 +2631,12 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
auto TemporaryExpr = dyn_cast<MaterializeTemporaryExpr>(Arg); auto TemporaryExpr = dyn_cast<MaterializeTemporaryExpr>(Arg);
if (TemporaryExpr) if (TemporaryExpr)
{ {
auto Cast = dyn_cast<CastExpr>(TemporaryExpr->GetTemporaryExpr()); auto SubTemporaryExpr = TemporaryExpr->GetTemporaryExpr();
if (Cast && Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass) auto Cast = dyn_cast<CastExpr>(SubTemporaryExpr);
return WalkExpression(Cast->getSubExprAsWritten()); if (!Cast || Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass)
return WalkExpression(SubTemporaryExpr);
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,
WalkDeclaration(ConstructorExpr->getConstructor()), WalkExpression(SubTemporaryExpr));
} }
} }
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,

63
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Generators; using CppSharp.Generators;
@ -17,7 +16,8 @@ namespace CppSharp.Passes
private static readonly Regex regexName = new Regex(@"(\w+)", RegexOptions.Compiled); private static readonly Regex regexName = new Regex(@"(\w+)", RegexOptions.Compiled);
private static readonly Regex regexCtor = new Regex(@"^([\w<,>:]+)\s*(\([\w, ]*\))$", RegexOptions.Compiled); private static readonly Regex regexCtor = new Regex(@"^([\w<,>:]+)\s*(\([\w, ]*\))$", RegexOptions.Compiled);
private readonly Dictionary<DeclarationContext, List<Function>> overloads = new Dictionary<DeclarationContext, List<Function>>(); private readonly Dictionary<DeclarationContext, List<Function>> overloads =
new Dictionary<DeclarationContext, List<Function>>();
public HandleDefaultParamValuesPass() public HandleDefaultParamValuesPass()
{ {
@ -50,8 +50,8 @@ namespace CppSharp.Passes
CheckFloatSyntax(desugared, parameter); CheckFloatSyntax(desugared, parameter);
bool? defaultConstruct = CheckForDefaultConstruct(desugared, parameter.DefaultArgument, bool? defaultConstruct = CheckForDefaultConstruct(desugared,
parameter.QualifiedType.Qualifiers); parameter.DefaultArgument, parameter.QualifiedType.Qualifiers);
if (defaultConstruct == null || if (defaultConstruct == null ||
(!Driver.Options.MarshalCharAsManagedChar && (!Driver.Options.MarshalCharAsManagedChar &&
parameter.Type.Desugar().IsPrimitiveType(PrimitiveType.UChar)) || parameter.Type.Desugar().IsPrimitiveType(PrimitiveType.UChar)) ||
@ -86,7 +86,8 @@ namespace CppSharp.Passes
{ {
case PrimitiveType.Float: case PrimitiveType.Float:
if (parameter.DefaultArgument.String.EndsWith(".F")) if (parameter.DefaultArgument.String.EndsWith(".F"))
parameter.DefaultArgument.String = parameter.DefaultArgument.String.Replace(".F", ".0F"); parameter.DefaultArgument.String =
parameter.DefaultArgument.String.Replace(".F", ".0F");
break; break;
case PrimitiveType.Double: case PrimitiveType.Double:
if (parameter.DefaultArgument.String.EndsWith(".")) if (parameter.DefaultArgument.String.EndsWith("."))
@ -121,7 +122,8 @@ namespace CppSharp.Passes
return false; return false;
} }
private bool? CheckForDefaultConstruct(Type desugared, Expression arg, TypeQualifiers qualifiers) private bool? CheckForDefaultConstruct(Type desugared, Statement arg,
TypeQualifiers qualifiers)
{ {
// Unwrapping the underlying type behind a possible pointer/reference // Unwrapping the underlying type behind a possible pointer/reference
Type type = desugared.GetFinalPointee() ?? desugared; Type type = desugared.GetFinalPointee() ?? desugared;
@ -142,7 +144,8 @@ namespace CppSharp.Passes
string typePrinterResult = null; string typePrinterResult = null;
if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap)) if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
{ {
var typeInSignature = typeMap.CSharpSignatureType(typePrinterContext).SkipPointerRefs(); var typeInSignature = typeMap.CSharpSignatureType(
typePrinterContext).SkipPointerRefs().Desugar();
Enumeration @enum; Enumeration @enum;
if (typeInSignature.TryGetEnum(out @enum)) if (typeInSignature.TryGetEnum(out @enum))
return false; return false;
@ -166,10 +169,12 @@ namespace CppSharp.Passes
var templateSpecializationType = type as TemplateSpecializationType; var templateSpecializationType = type as TemplateSpecializationType;
var typePrinter = new CSharpTypePrinter(Driver); var typePrinter = new CSharpTypePrinter(Driver);
typePrinterResult = typePrinterResult ?? (templateSpecializationType != null typePrinterResult = typePrinterResult ?? (templateSpecializationType != null
? typePrinter.VisitTemplateSpecializationType(templateSpecializationType, qualifiers) ? typePrinter.VisitTemplateSpecializationType(
templateSpecializationType, qualifiers)
: typePrinter.VisitClassDecl((Class) ctor.Namespace)).Type; : typePrinter.VisitClassDecl((Class) ctor.Namespace)).Type;
arg.String = string.Format("new {0}{1}", typePrinterResult, match.Groups[2].Value); arg.String = string.Format("new {0}{1}", typePrinterResult,
match.Groups[2].Value);
if (ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress()) if (ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress())
arg.String = arg.String.Replace("(0)", "()"); arg.String = arg.String.Replace("(0)", "()");
} }
@ -183,7 +188,7 @@ namespace CppSharp.Passes
var finalPointee = ctor.Parameters[0].Type.SkipPointerRefs().Desugar(); var finalPointee = ctor.Parameters[0].Type.SkipPointerRefs().Desugar();
Enumeration @enum; Enumeration @enum;
if (finalPointee.TryGetEnum(out @enum)) if (finalPointee.TryGetEnum(out @enum))
TranslateEnumExpression(arg, finalPointee, arg.String); TranslateEnumExpression(ctor, arg, finalPointee, arg.String);
} }
} }
@ -209,7 +214,8 @@ namespace CppSharp.Passes
{ {
arg.String = string.Format("{0}{1}.{2}", arg.String = string.Format("{0}{1}.{2}",
desugared.IsPrimitiveType() ? "(int) " : string.Empty, desugared.IsPrimitiveType() ? "(int) " : string.Empty,
new CSharpTypePrinter(Driver).VisitEnumDecl((Enumeration) enumItem.Namespace), enumItem.Name); new CSharpTypePrinter(Driver).VisitEnumDecl(
(Enumeration) enumItem.Namespace), enumItem.Name);
return true; return true;
} }
@ -217,23 +223,52 @@ namespace CppSharp.Passes
if (call != null && arg.String != "0") if (call != null && arg.String != "0")
{ {
string @params = regexFunctionParams.Match(arg.String).Groups[1].Value; string @params = regexFunctionParams.Match(arg.String).Groups[1].Value;
TranslateEnumExpression(arg, desugared, @params); TranslateEnumExpression(call, arg, desugared, @params);
return true; return true;
} }
return false; return false;
} }
private static void TranslateEnumExpression(Expression arg, Type desugared, string @params) private void TranslateEnumExpression(Function function, Statement arg,
Type desugared, string @params)
{
TypeMap typeMap;
if ((function.Parameters.Count == 0 ||
HasSingleZeroExpression(function)) &&
Driver.TypeDatabase.FindTypeMap(desugared, out typeMap))
{
var typeInSignature = typeMap.CSharpSignatureType(new CSharpTypePrinterContext
{
CSharpKind = CSharpTypePrinterContextKind.DefaultExpression,
Type = desugared
}).SkipPointerRefs().Desugar();
Enumeration @enum;
if (typeInSignature.TryGetEnum(out @enum))
{ {
arg.String = "0";
return;
}
}
if (@params.Contains("::")) if (@params.Contains("::"))
arg.String = regexDoubleColon.Replace(@params, desugared + "."); arg.String = regexDoubleColon.Replace(@params, desugared + ".");
else else
arg.String = regexName.Replace(@params, desugared + ".$1"); arg.String = regexName.Replace(@params, desugared + ".$1");
} }
private static bool HasSingleZeroExpression(Function function)
{
if (function.Parameters.Count != 1)
return false;
var defaultArgument = function.Parameters[0].DefaultArgument;
return defaultArgument is BuiltinTypeExpression &&
((BuiltinTypeExpression) defaultArgument).Value == 0;
}
private void CheckForDefaultEmptyChar(Parameter parameter, Type desugared) private void CheckForDefaultEmptyChar(Parameter parameter, Type desugared)
{ {
if (parameter.DefaultArgument.String == "0" && Driver.Options.MarshalCharAsManagedChar && if (parameter.DefaultArgument.String == "0" &&
Driver.Options.MarshalCharAsManagedChar &&
desugared.IsPrimitiveType(PrimitiveType.Char)) desugared.IsPrimitiveType(PrimitiveType.Char))
{ {
parameter.DefaultArgument.String = "'\\0'"; parameter.DefaultArgument.String = "'\\0'";

1
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -188,6 +188,7 @@ public class CSharpTempTests : GeneratorTestFixture
methodsWithDefaultValues.DefaultNonEmptyCtor(); methodsWithDefaultValues.DefaultNonEmptyCtor();
methodsWithDefaultValues.DefaultMappedToEnum(); methodsWithDefaultValues.DefaultMappedToEnum();
methodsWithDefaultValues.DefaultMappedToZeroEnum(); methodsWithDefaultValues.DefaultMappedToZeroEnum();
methodsWithDefaultValues.DefaultMappedToEnumAssignedWithCtor();
methodsWithDefaultValues.DefaultImplicitCtorInt(); methodsWithDefaultValues.DefaultImplicitCtorInt();
methodsWithDefaultValues.DefaultImplicitCtorChar(); methodsWithDefaultValues.DefaultImplicitCtorChar();
methodsWithDefaultValues.DefaultImplicitCtorFoo(); methodsWithDefaultValues.DefaultImplicitCtorFoo();

20
tests/CSharpTemp/CSharpTemp.cpp

@ -216,22 +216,6 @@ long P::prop()
return m_property + 100; return m_property + 100;
} }
template <typename T>
QFlags<T>::QFlags(T t) : flag(t)
{
}
template <typename T>
QFlags<T>::QFlags(Zero) : flag(0)
{
}
template <typename T>
QFlags<T>::operator T()
{
return flag;
}
ComplexType::ComplexType() : qFlags(QFlags<TestFlag>(TestFlag::Flag2)) ComplexType::ComplexType() : qFlags(QFlags<TestFlag>(TestFlag::Flag2))
{ {
} }
@ -420,6 +404,10 @@ void MethodsWithDefaultValues::defaultMappedToZeroEnum(QFlags<Flags> qFlags)
{ {
} }
void MethodsWithDefaultValues::defaultMappedToEnumAssignedWithCtor(QFlags<Flags> qFlags)
{
}
void MethodsWithDefaultValues::defaultImplicitCtorInt(Quux arg) void MethodsWithDefaultValues::defaultImplicitCtorInt(Quux arg)
{ {
} }

24
tests/CSharpTemp/CSharpTemp.h

@ -148,15 +148,32 @@ Proprietor::Proprietor() {}
template <typename T> template <typename T>
class DLL_API QFlags class DLL_API QFlags
{ {
typedef int Int;
typedef int (*Zero); typedef int (*Zero);
public: public:
QFlags(T t); QFlags(T t);
QFlags(Zero); QFlags(Zero = 0);
operator T(); operator Int();
private: private:
T flag; int flag;
}; };
template <typename T>
QFlags<T>::QFlags(T t) : flag(Int(t))
{
}
template <typename T>
QFlags<T>::QFlags(Zero) : flag(Int(0))
{
}
template <typename T>
QFlags<T>::operator Int()
{
return flag;
}
enum class TestFlag enum class TestFlag
{ {
Flag1, Flag1,
@ -311,6 +328,7 @@ public:
void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0)); void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0));
void defaultMappedToEnum(QFlags<Flags> qFlags = Flags::Flag1); void defaultMappedToEnum(QFlags<Flags> qFlags = Flags::Flag1);
void defaultMappedToZeroEnum(QFlags<Flags> qFlags = 0); void defaultMappedToZeroEnum(QFlags<Flags> qFlags = 0);
void defaultMappedToEnumAssignedWithCtor(QFlags<Flags> qFlags = QFlags<Flags>());
void defaultImplicitCtorInt(Quux arg = 0); void defaultImplicitCtorInt(Quux arg = 0);
void defaultImplicitCtorChar(Quux arg = 'a'); void defaultImplicitCtorChar(Quux arg = 'a');
void defaultImplicitCtorFoo(Quux arg = Foo()); void defaultImplicitCtorFoo(Quux arg = Foo());

Loading…
Cancel
Save