diff --git a/src/AST/Function.cs b/src/AST/Function.cs index f6a55871..f967472a 100644 --- a/src/AST/Function.cs +++ b/src/AST/Function.cs @@ -63,6 +63,7 @@ namespace CppSharp.AST public enum FunctionSynthKind { None, + NonMemberOperator } public class Function : Declaration, ITypedDecl, IMangledDecl diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 2b7061c5..f8787ade 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -133,6 +133,7 @@ namespace CppSharp TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass()); TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); TranslationUnitPasses.AddPass(new FindSymbolsPass()); + TranslationUnitPasses.AddPass(new MoveOperatorToClassPass()); library.SetupPasses(this); diff --git a/src/Generator/Generators/CSharp/CSharpGenerator.cs b/src/Generator/Generators/CSharp/CSharpGenerator.cs index bc4a5fb6..479eb7f8 100644 --- a/src/Generator/Generators/CSharp/CSharpGenerator.cs +++ b/src/Generator/Generators/CSharp/CSharpGenerator.cs @@ -31,7 +31,6 @@ namespace CppSharp.Generators.CSharp // CheckAbiParameters runs last because hidden structure parameters // should always occur first. - Driver.AddTranslationUnitPass(new MoveOperatorToClassPass()); Driver.AddTranslationUnitPass(new CheckOperatorsOverloadsPass()); Driver.AddTranslationUnitPass(new CheckAbiParameters(Driver.Options)); diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index 6a0871b4..e8a46d9c 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -70,7 +70,7 @@ namespace CppSharp.Passes return true; } - private static bool GetClassParameter(Parameter classParam, out Class @class) + public static bool GetClassParameter(Parameter classParam, out Class @class) { TagType tag; if (classParam.Type.IsPointerTo(out tag)) diff --git a/src/Generator/Passes/MoveOperatorToClassPass.cs b/src/Generator/Passes/MoveOperatorToClassPass.cs index e63800b5..c4cdf4d3 100644 --- a/src/Generator/Passes/MoveOperatorToClassPass.cs +++ b/src/Generator/Passes/MoveOperatorToClassPass.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.Linq; using CppSharp.AST; namespace CppSharp.Passes @@ -8,20 +8,19 @@ namespace CppSharp.Passes { public override bool VisitMethodDecl(Method method) { + // Ignore methods as they are not relevant for this pass. return true; } public override bool VisitFunctionDecl(Function function) { - if (function.Ignore || !function.Name.StartsWith("operator")) + if (function.Ignore || !function.IsOperator) return false; - string type = function.Parameters[0].Type.Desugar().ToString(); - if (string.IsNullOrEmpty(type)) - return false; + var param = function.Parameters[0]; - var @class = Library.FindCompleteClass(type); - if (@class == null) + Class @class; + if (!FunctionToInstanceMethodPass.GetClassParameter(param, out @class)) return false; function.ExplicityIgnored = true; @@ -37,76 +36,21 @@ namespace CppSharp.Passes Access = AccessSpecifier.Public, Kind = CXXMethodKind.Operator, ReturnType = function.ReturnType, - Parameters = new List(function.Parameters), + Parameters = new List(function.Parameters).Skip(1).ToList(), CallingConvention = function.CallingConvention, IsVariadic = function.IsVariadic, IsInline = function.IsInline, - IsStatic = true, - Conversion = MethodConversionKind.FunctionToStaticMethod, - OperatorKind = GetOperatorKind(function.Name) + OperatorKind = function.OperatorKind, + SynthKind = FunctionSynthKind.NonMemberOperator, + OriginalFunction = function }; @class.Methods.Add(method); - Console.WriteLine("Static method: {0}::{1}", @class.Name, - function.Name); + Driver.Diagnostics.Debug("Function converted to operator: {0}::{1}", + @class.Name, function.Name); return true; } - - private static CXXOperatorKind GetOperatorKind(string @operator) - { - const string op = "operator"; - if (!@operator.StartsWith(op)) - { - return CXXOperatorKind.None; - } - switch (@operator.Substring(8).Trim()) - { - case "+": return CXXOperatorKind.Plus; - case "-": return CXXOperatorKind.Minus; - case "!": return CXXOperatorKind.Exclaim; - case "~": return CXXOperatorKind.Tilde; - case "++": return CXXOperatorKind.PlusPlus; - case "--": return CXXOperatorKind.MinusMinus; - case "*": return CXXOperatorKind.Star; - case "/": return CXXOperatorKind.Slash; - case "&": return CXXOperatorKind.Amp; - case "|": return CXXOperatorKind.Pipe; - case "^": return CXXOperatorKind.Caret; - case "<<": return CXXOperatorKind.LessLess; - case ">>": return CXXOperatorKind.GreaterGreater; - case "==": return CXXOperatorKind.EqualEqual; - case "!=": return CXXOperatorKind.ExclaimEqual; - case "<": return CXXOperatorKind.Less; - case ">": return CXXOperatorKind.Greater; - case "<=": return CXXOperatorKind.LessEqual; - case ">=": return CXXOperatorKind.GreaterEqual; - case "+=": return CXXOperatorKind.PlusEqual; - case "-=": return CXXOperatorKind.MinusEqual; - case "*=": return CXXOperatorKind.StarEqual; - case "/=": return CXXOperatorKind.SlashEqual; - case "%=": return CXXOperatorKind.PercentEqual; - case "&=": return CXXOperatorKind.AmpEqual; - case "|=": return CXXOperatorKind.PipeEqual; - case "^=": return CXXOperatorKind.CaretEqual; - case "<<=": return CXXOperatorKind.LessLessEqual; - case ">>=": return CXXOperatorKind.GreaterGreaterEqual; - case "[]": return CXXOperatorKind.Subscript; - case "&&": return CXXOperatorKind.AmpAmp; - case "||": return CXXOperatorKind.PipePipe; - case "=": return CXXOperatorKind.Equal; - case ",": return CXXOperatorKind.Comma; - case "->*": return CXXOperatorKind.ArrowStar; - case "->": return CXXOperatorKind.Arrow; - case "()": return CXXOperatorKind.Call; - case "?": return CXXOperatorKind.Conditional; - case "new": return CXXOperatorKind.New; - case "delete": return CXXOperatorKind.Delete; - case "new[]": return CXXOperatorKind.Array_New; - case "delete[]": return CXXOperatorKind.Array_Delete; - } - return CXXOperatorKind.None; - } } }