From 684a9ff52bc6521cf37416718890ff5b2f20782a Mon Sep 17 00:00:00 2001
From: triton <joao@tritao.eu>
Date: Thu, 18 Dec 2014 17:57:50 +0000
Subject: [PATCH] Fixed wrapping of virtual overloaded operators.

References #389.
---
 .../Generators/CLI/CLIHeadersTemplate.cs        |  2 +-
 .../Generators/CSharp/CSharpTextTemplate.cs     | 17 ++++++++++++-----
 src/Generator/Passes/CheckOperatorsOverloads.cs |  3 ++-
 tests/Basic/Basic.h                             |  6 ++++++
 4 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs
index ea43a40b..cda13673 100644
--- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs
+++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs
@@ -683,7 +683,7 @@ namespace CppSharp.Generators.CLI
 
             GenerateDeclarationCommon(method);
 
-            if (method.IsVirtual || method.IsOverride)
+            if ((method.IsVirtual || method.IsOverride) && !method.IsOperator)
                 Write("virtual ");
 
             var isBuiltinOperator = method.IsOperator &&
diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs
index 1aa80c75..15903296 100644
--- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs
+++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs
@@ -1285,10 +1285,16 @@ namespace CppSharp.Generators.CSharp
 
         #region Virtual Tables
 
+        public List<VTableComponent> GetValidVTableMethodEntries(Class @class)
+        {
+            var entries = VTables.GatherVTableMethodEntries(@class);
+            return entries.Where(e => !e.Ignore && !e.Method.IsOperator).ToList();
+        }
+
         public List<VTableComponent> GetUniqueVTableMethodEntries(Class @class)
         {
             var uniqueEntries = new OrderedSet<VTableComponent>();
-            foreach (var entry in VTables.GatherVTableMethodEntries(@class))
+            foreach (var entry in GetValidVTableMethodEntries(@class))
                 uniqueEntries.Add(entry);
 
             return uniqueEntries.ToList();
@@ -1297,8 +1303,7 @@ namespace CppSharp.Generators.CSharp
         public void GenerateVTable(Class @class)
         {
             var entries = VTables.GatherVTableMethodEntries(@class);
-            var wrappedEntries = GetUniqueVTableMethodEntries(@class).Where(
-                e => !e.Ignore).ToList();
+            var wrappedEntries = GetUniqueVTableMethodEntries(@class);
             if (wrappedEntries.Count == 0)
                 return;
 
@@ -1479,7 +1484,7 @@ namespace CppSharp.Generators.CSharp
 
         private void GenerateVTableClassSetupCall(Class @class, bool addPointerGuard = false)
         {
-            var entries = VTables.GatherVTableMethodEntries(@class);
+            var entries = GetUniqueVTableMethodEntries(@class);
             if (Options.GenerateVirtualTables && @class.IsDynamic && entries.Count != 0)
             {
                 // called from internal ctors which may have been passed an IntPtr.Zero
@@ -1489,7 +1494,9 @@ namespace CppSharp.Generators.CSharp
                         Helpers.InstanceIdentifier);
                     PushIndent();
                 }
+
                 WriteLine("SetupVTables({0});", Generator.GeneratedIdentifier("Instance"));
+
                 if (addPointerGuard)
                     PopIndent();
             }
@@ -2070,7 +2077,7 @@ namespace CppSharp.Generators.CSharp
                 Write(Helpers.GetAccess(GetValidMethodAccess(method)));
             }
 
-            if (method.IsVirtual && !method.IsOverride &&
+            if (method.IsVirtual && !method.IsOverride && !method.IsOperator &&
                 (!Driver.Options.GenerateAbstractImpls || !method.IsPure))
                 Write("virtual ");
 
diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs
index 18835e46..c4946f71 100644
--- a/src/Generator/Passes/CheckOperatorsOverloads.cs
+++ b/src/Generator/Passes/CheckOperatorsOverloads.cs
@@ -57,6 +57,7 @@ namespace CppSharp.Passes
                     @operator.ExplicitlyIgnore();
                     continue;
                 }
+
                 if (@operator.IsNonMemberOperator)
                     continue;
 
@@ -70,7 +71,7 @@ namespace CppSharp.Passes
                     if (@operator.IsStatic)
                         @operator.Parameters = @operator.Parameters.Skip(1).ToList();
 
-                    var type = new PointerType()
+                    var type = new PointerType
                     {
                         QualifiedPointee = new QualifiedType(new TagType(@class)),
                         Modifier = PointerType.TypeModifier.LVReference
diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h
index e354c7ef..3ffc3e01 100644
--- a/tests/Basic/Basic.h
+++ b/tests/Basic/Basic.h
@@ -445,12 +445,18 @@ public:
 	operator char();
 	operator int();
 	operator short();
+
+	virtual bool operator<(const ClassWithOverloadedOperators &other) const;
 };
 
 ClassWithOverloadedOperators::ClassWithOverloadedOperators() {}
 ClassWithOverloadedOperators::operator char() { return 1; }
 ClassWithOverloadedOperators::operator int() { return 2; }
 ClassWithOverloadedOperators::operator short() { return 3; }
+bool ClassWithOverloadedOperators::
+     operator<(const ClassWithOverloadedOperators &other) const {
+     return true;
+}
 
 // Tests global static function generation
 DLL_API int Function()