diff --git a/src/AST/Method.cs b/src/AST/Method.cs index 557ba730..c2216eba 100644 --- a/src/AST/Method.cs +++ b/src/AST/Method.cs @@ -88,6 +88,7 @@ namespace CppSharp.AST IsImplicit = method.IsImplicit; IsOverride = method.IsOverride; IsProxy = method.IsProxy; + IsStatic = method.IsStatic; Kind = method.Kind; IsDefaultConstructor = method.IsDefaultConstructor; IsCopyConstructor = method.IsCopyConstructor; diff --git a/src/AST/Statement.cs b/src/AST/Statement.cs index b1ae1985..3f8e1a68 100644 --- a/src/AST/Statement.cs +++ b/src/AST/Statement.cs @@ -3,8 +3,10 @@ public enum StatementClass { Any, + BinaryOperator, DeclarationReference, - ConstructorReference + ConstructorReference, + CXXOperatorCall } public abstract class Statement diff --git a/src/Core/Parser/ASTConverter.cs b/src/Core/Parser/ASTConverter.cs index 6a09a77f..4197a82d 100644 --- a/src/Core/Parser/ASTConverter.cs +++ b/src/Core/Parser/ASTConverter.cs @@ -849,12 +849,18 @@ namespace CppSharp expression.String = statement.String; switch (statement.Class) { + case StatementClass.BinaryOperator: + expression.Class = AST.StatementClass.BinaryOperator; + break; case StatementClass.DeclRefExprClass: expression.Class = AST.StatementClass.DeclarationReference; break; case StatementClass.CXXConstructExprClass: expression.Class = AST.StatementClass.ConstructorReference; break; + case StatementClass.CXXOperatorCallExpr: + expression.Class = AST.StatementClass.CXXOperatorCall; + break; } return expression; } diff --git a/src/CppParser/AST.h b/src/CppParser/AST.h index 98a7024c..fed306ea 100644 --- a/src/CppParser/AST.h +++ b/src/CppParser/AST.h @@ -458,8 +458,10 @@ public: enum class StatementClass { Any, + BinaryOperator, DeclRefExprClass, - CXXConstructExprClass + CXXConstructExprClass, + CXXOperatorCallExpr }; class CS_API Statement diff --git a/src/CppParser/Bindings/CLI/AST.h b/src/CppParser/Bindings/CLI/AST.h index 4403ad43..47e2c2ef 100644 --- a/src/CppParser/Bindings/CLI/AST.h +++ b/src/CppParser/Bindings/CLI/AST.h @@ -210,8 +210,10 @@ namespace CppSharp public enum struct StatementClass { Any = 0, - DeclRefExprClass = 1, - CXXConstructExprClass = 2 + BinaryOperator = 1, + DeclRefExprClass = 2, + CXXConstructExprClass = 3, + CXXOperatorCallExpr = 4 }; public enum struct TemplateSpecializationKind diff --git a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs index 430375ff..321b67c4 100644 --- a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs +++ b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs @@ -134,8 +134,10 @@ namespace CppSharp public enum StatementClass { Any = 0, - DeclRefExprClass = 1, - CXXConstructExprClass = 2 + BinaryOperator = 1, + DeclRefExprClass = 2, + CXXConstructExprClass = 3, + CXXOperatorCallExpr = 4 } public enum TemplateSpecializationKind diff --git a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs index 9575d83f..559495c1 100644 --- a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs +++ b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs @@ -134,8 +134,10 @@ namespace CppSharp public enum StatementClass { Any = 0, - DeclRefExprClass = 1, - CXXConstructExprClass = 2 + BinaryOperator = 1, + DeclRefExprClass = 2, + CXXConstructExprClass = 3, + CXXOperatorCallExpr = 4 } public enum TemplateSpecializationKind diff --git a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs index c307baa5..5afc3b93 100644 --- a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs +++ b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs @@ -134,8 +134,10 @@ namespace CppSharp public enum StatementClass { Any = 0, - DeclRefExprClass = 1, - CXXConstructExprClass = 2 + BinaryOperator = 1, + DeclRefExprClass = 2, + CXXConstructExprClass = 3, + CXXOperatorCallExpr = 4 } public enum TemplateSpecializationKind diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index cde23958..eb323e23 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2455,6 +2455,8 @@ AST::Expression* Parser::WalkStatement(clang::Stmt* Statement) switch (Statement->getStmtClass()) { + case Stmt::BinaryOperatorClass: + return new AST::Expression(GetStringFromStatement(Statement), StatementClass::BinaryOperator); case Stmt::DeclRefExprClass: return new AST::Expression(GetStringFromStatement(Statement), StatementClass::DeclRefExprClass, WalkDeclaration(cast(Statement)->getDecl())); @@ -2466,16 +2468,23 @@ AST::Expression* Parser::WalkStatement(clang::Stmt* Statement) case Stmt::CXXStaticCastExprClass: case Stmt::ImplicitCastExprClass: return WalkStatement(cast(Statement)->getSubExprAsWritten()); + case Stmt::CXXOperatorCallExprClass: + return new AST::Expression(GetStringFromStatement(Statement), StatementClass::CXXOperatorCallExpr, + WalkDeclaration(cast(Statement)->getCalleeDecl())); case Stmt::CXXConstructExprClass: case Stmt::CXXTemporaryObjectExprClass: { auto ConstructorExpr = cast(Statement); - if (ConstructorExpr->getNumArgs() > 0) + if (ConstructorExpr->getNumArgs() == 1) { auto Arg = ConstructorExpr->getArg(0); auto TemporaryExpr = dyn_cast(Arg); - if (TemporaryExpr && isa(TemporaryExpr->GetTemporaryExpr())) - return WalkStatement(TemporaryExpr->GetTemporaryExpr()); + if (TemporaryExpr) + { + auto Cast = dyn_cast(TemporaryExpr->GetTemporaryExpr()); + if (Cast && Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass) + return WalkStatement(Cast->getSubExprAsWritten()); + } } return new AST::Expression(GetStringFromStatement(Statement), StatementClass::CXXConstructExprClass, WalkDeclaration(ConstructorExpr->getConstructor())); diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 47f30034..1d741c45 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -13,7 +13,7 @@ namespace CppSharp.Passes { public class HandleDefaultParamValuesPass : TranslationUnitPass { - private static readonly Regex regexFunctionParams = new Regex(@"\((.+)\)", RegexOptions.Compiled); + private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", RegexOptions.Compiled); private static readonly Regex regexDoubleColon = new Regex(@"\w+::", RegexOptions.Compiled); private static readonly Regex regexName = new Regex(@"(\w+)", RegexOptions.Compiled); @@ -114,17 +114,18 @@ namespace CppSharp.Passes var enumItem = parameter.DefaultArgument.Declaration as Enumeration.Item; if (enumItem != null) { - parameter.DefaultArgument.String = string.Format("{0}{1}.{2}.{3}", + parameter.DefaultArgument.String = string.Format("{0}{1}{2}.{3}", desugared.IsPrimitiveType() ? "(int) " : string.Empty, - enumItem.Namespace.Namespace.Name, enumItem.Namespace.Name, enumItem.Name); + string.IsNullOrEmpty(enumItem.Namespace.Namespace.Name) + ? string.Empty + : enumItem.Namespace.Namespace.Name + ".", enumItem.Namespace.Name, enumItem.Name); return true; } - var call = parameter.DefaultArgument.Declaration as Method; - if (call != null && call.IsConstructor) + var call = parameter.DefaultArgument.Declaration as Function; + if (call != null || parameter.DefaultArgument.Class == StatementClass.BinaryOperator) { - string @params = - regexFunctionParams.Match(parameter.DefaultArgument.String).Groups[1].Value; + string @params = regexFunctionParams.Match(parameter.DefaultArgument.String).Groups[1].Value; if (@params.Contains("::")) parameter.DefaultArgument.String = regexDoubleColon.Replace(@params, desugared + "."); else diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index cc13910e..6cd3eae7 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -13,11 +13,11 @@ namespace CppSharp.Passes /// public abstract class RenamePass : TranslationUnitPass { - public class ParameterMappedTypeComparer : IEqualityComparer + public class ParameterComparer : IEqualityComparer { public bool Equals(Parameter x, Parameter y) { - return x.QualifiedType == y.QualifiedType; + return x.QualifiedType == y.QualifiedType && x.GenerationKind == y.GenerationKind; } public int GetHashCode(Parameter obj) @@ -134,10 +134,10 @@ namespace CppSharp.Passes if (method != null) { return ((Class) method.Namespace).Methods.Where( - m => m.Parameters.SequenceEqual(function.Parameters, new ParameterMappedTypeComparer())); + m => m.Parameters.SequenceEqual(function.Parameters, new ParameterComparer())); } return function.Namespace.Functions.Where( - f => f.Parameters.SequenceEqual(function.Parameters, new ParameterMappedTypeComparer())); + f => f.Parameters.SequenceEqual(function.Parameters, new ParameterComparer())); } public override bool VisitEnumItem(Enumeration.Item item) diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index ac9cbfc4..3f022a7c 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -222,35 +222,54 @@ TestCopyConstructorVal::TestCopyConstructorVal(const TestCopyConstructorVal& oth B = other.B; } -void MethodsWithDefaultValues::DefaultPointer(Foo *ptr) +Flags operator|(Flags lhs, Flags rhs) { + return static_cast(static_cast(lhs) | static_cast(rhs)); } -void MethodsWithDefaultValues::DefaultValueType(ValueType bar) +UntypedFlags operator|(UntypedFlags lhs, UntypedFlags rhs) { + return static_cast(static_cast(lhs) | static_cast(rhs)); } -void MethodsWithDefaultValues::DefaultChar(char c) +QGenericArgument::QGenericArgument(const char *name) { + _name = name; } -void MethodsWithDefaultValues::DefaultRefTypeBeforeOthers(Foo foo, int i, Bar::Items item) +void MethodsWithDefaultValues::defaultPointer(Foo *ptr) { } -void MethodsWithDefaultValues::DefaultRefTypeAfterOthers(int i, Bar::Items item, Foo foo) +void MethodsWithDefaultValues::defaultValueType(ValueType bar) { } -void MethodsWithDefaultValues::DefaultRefTypeBeforeAndAfterOthers(int i, Foo foo, Bar::Items item, Baz baz) +void MethodsWithDefaultValues::defaultChar(char c) { } -void MethodsWithDefaultValues::DefaultIntAssignedAnEnum(int i) +void MethodsWithDefaultValues::defaultRefTypeBeforeOthers(Foo foo, int i, Bar::Items item) { } -void MethodsWithDefaultValues::DefaultRefAssignedValue(const Foo &fooRef) +void MethodsWithDefaultValues::defaultRefTypeAfterOthers(int i, Bar::Items item, Foo foo) +{ +} + +void MethodsWithDefaultValues::defaultRefTypeBeforeAndAfterOthers(int i, Foo foo, Bar::Items item, Baz baz) +{ +} + +void MethodsWithDefaultValues::defaultIntAssignedAnEnum(int i) +{ +} + +void MethodsWithDefaultValues::defaultRefAssignedValue(const Foo &fooRef) +{ +} + +void MethodsWithDefaultValues::defaultMappedToEnum(QFlags qFlags) { } diff --git a/tests/CSharpTemp/CSharpTemp.cs b/tests/CSharpTemp/CSharpTemp.cs index 4083e326..2efe4a09 100644 --- a/tests/CSharpTemp/CSharpTemp.cs +++ b/tests/CSharpTemp/CSharpTemp.cs @@ -81,6 +81,7 @@ namespace CppSharp.Tests public override void Preprocess(Driver driver, ASTContext ctx) { ctx.SetClassAsValueType("TestCopyConstructorVal"); + ctx.SetClassAsValueType("QGenericArgument"); } public override void Postprocess(Driver driver, ASTContext ctx) diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 8fc93df2..7df4f644 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -187,17 +187,48 @@ struct DLL_API ValueType { }; +enum class Flags +{ + Flag1 = 1, + Flag2 = 2, + Flag3 = 4 +}; + +DLL_API Flags operator|(Flags lhs, Flags rhs); + +enum UntypedFlags +{ + Flag1 = 1, + Flag2 = 2, + Flag3 = 4 +}; + +UntypedFlags operator|(UntypedFlags lhs, UntypedFlags rhs); + +struct QGenericArgument +{ +public: + QGenericArgument(const char* name = 0); +private: + const char* _name; +}; + class DLL_API MethodsWithDefaultValues { public: - void DefaultPointer(Foo* ptr = 0); - void DefaultValueType(ValueType bar = ValueType()); - void DefaultChar(char c = 'a'); - void DefaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2); - void DefaultRefTypeAfterOthers(int i = 5, Bar::Items item = Bar::Item2, Foo foo = Foo()); - void DefaultRefTypeBeforeAndAfterOthers(int i = 5, Foo foo = Foo(), Bar::Items item = Bar::Item2, Baz baz = Baz()); - void DefaultIntAssignedAnEnum(int i = Bar::Item1); + void defaultPointer(Foo* ptr = 0); + void defaultValueType(ValueType bar = ValueType()); + void defaultChar(char c = 'a'); + void defaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2); + void defaultRefTypeAfterOthers(int i = 5, Bar::Items item = Bar::Item2, Foo foo = Foo()); + void defaultRefTypeBeforeAndAfterOthers(int i = 5, Foo foo = Foo(), Bar::Items item = Bar::Item2, Baz baz = Baz()); + void defaultIntAssignedAnEnum(int i = Bar::Item1); + void defaultRefAssignedValue(const Foo& fooRef = Foo()); void DefaultRefAssignedValue(const Foo& fooRef = Foo()); + void defaultEnumAssignedBitwiseOr(Flags flags = Flags::Flag1 | Flags::Flag2); + void defaultEnumAssignedBitwiseOrShort(UntypedFlags flags = Flag1 | Flag2); + void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0)); + void defaultMappedToEnum(QFlags qFlags = Flags::Flag1); }; class DLL_API HasPrivateOverrideBase