diff --git a/build/Tests.lua b/build/Tests.lua index 245082d0..ede991d3 100644 --- a/build/Tests.lua +++ b/build/Tests.lua @@ -55,6 +55,7 @@ function SetupTestGeneratorProject(name, depends) dependson { name .. ".Native" } linktable = { + "System", "System.Core", "CppSharp", "CppSharp.AST", diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 8ab1376d..deb93b2a 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -308,12 +308,12 @@ namespace CppSharp.Generators.CSharp } PushBlock(BlockKind.Class); - GenerateDeclarationCommon(@class); + GenerateDeclarationCommon(@class); GenerateClassSpecifier(@class); NewLine(); WriteStartBraceIndent(); - + if (!@class.IsAbstractImpl) GenerateClassInternals(@class); @@ -569,7 +569,7 @@ namespace CppSharp.Generators.CSharp // private classes must be visible to because the internal structs can be used in dependencies // the proper fix is InternalsVisibleTo var keywords = new List<string>(); - + keywords.Add(@class.Access == AccessSpecifier.Protected ? "protected internal" : "public"); keywords.Add("unsafe"); @@ -833,7 +833,7 @@ namespace CppSharp.Generators.CSharp var marshal = new CSharpMarshalManagedToNativePrinter(ctx); ctx.Declaration = field; - var arrayType = field.Type as ArrayType; + var arrayType = field.Type as ArrayType ?? field.QualifiedType.Type.Desugar() as ArrayType; if (arrayType != null && @class.IsValueType) { @@ -1078,7 +1078,7 @@ namespace CppSharp.Generators.CSharp TypePrinter.PopContext(); - var arrayType = field.Type as ArrayType; + var arrayType = field.Type as ArrayType ?? field.QualifiedType.Type.Desugar() as ArrayType; if (arrayType != null && @class.IsValueType) ctx.ReturnVarName = HandleValueArray(arrayType, field); @@ -1285,7 +1285,7 @@ namespace CppSharp.Generators.CSharp private void GenerateVariable(Class @class, Variable variable) { PushBlock(BlockKind.Variable); - + GenerateDeclarationCommon(variable); WriteLine("public static {0} {1}", variable.Type, variable.Name); WriteStartBraceIndent(); @@ -1424,7 +1424,7 @@ namespace CppSharp.Generators.CSharp if (Context.ParserOptions.IsMicrosoftAbi) WriteLine("__OriginalVTables = new void*[] {{ {0} }};", string.Join(", ", - @class.Layout.VTablePointers.Select(v => + @class.Layout.VTablePointers.Select(v => $"*(void**) ({Helpers.InstanceIdentifier} + {v.Offset})"))); else WriteLine( @@ -1566,7 +1566,7 @@ namespace CppSharp.Generators.CSharp if (method.IsGenerated) { WriteLine("{0}.{1}({2});", Helpers.TargetIdentifier, - method.Name, string.Join(", ", marshals)); + method.Name, string.Join(", ", marshals)); } else { @@ -2157,7 +2157,7 @@ namespace CppSharp.Generators.CSharp else if (method.ExplicitInterfaceImpl != null) Write("{0} {1}.{2}(", method.OriginalReturnType, method.ExplicitInterfaceImpl.Name, functionName); - else if (method.OperatorKind == CXXOperatorKind.Conversion || + else if (method.OperatorKind == CXXOperatorKind.Conversion || method.OperatorKind == CXXOperatorKind.ExplicitConversion) Write("{0} {1}(", functionName, method.OriginalReturnType); else @@ -2278,7 +2278,7 @@ namespace CppSharp.Generators.CSharp Class @class; return p.Type.IsPointerToPrimitiveType() && p.Usage == ParameterUsage.InOut && p.HasDefaultValue ? "ref param" + index++ - : (( p.Type.TryGetClass(out @class) && @class.IsInterface) ? "param" + index++ + : (( p.Type.TryGetClass(out @class) && @class.IsInterface) ? "param" + index++ : ExpressionPrinter.VisitParameter(p)); } @@ -2362,7 +2362,7 @@ namespace CppSharp.Generators.CSharp } else { - WriteLine("return {0}.GetHashCode();", Helpers.InstanceIdentifier); + WriteLine("return {0}.GetHashCode();", Helpers.InstanceIdentifier); } WriteCloseBraceIndent(); } @@ -2733,7 +2733,7 @@ namespace CppSharp.Generators.CSharp if (needsFixedThis && operatorParam == null) WriteCloseBraceIndent(); - + var numFixedBlocks = @params.Count(param => param.HasUsingBlock); for(var i = 0; i < numFixedBlocks; ++i) WriteCloseBraceIndent(); diff --git a/src/Generator/Library.cs b/src/Generator/Library.cs index 36ba3369..e6f63c9b 100644 --- a/src/Generator/Library.cs +++ b/src/Generator/Library.cs @@ -117,6 +117,8 @@ namespace CppSharp static ulong ParseMacroExpression(string expression) { // TODO: Handle string expressions + if (expression.Length == 3 && expression[0] == '\'' && expression[2] == '\'') // '0' || 'A' + return expression[1]; // return the ASCI code of this character long val; return ParseToNumber(expression, out val) ? (ulong)val : 0; diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 0bb48076..b1a88484 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -68,7 +68,7 @@ public unsafe class CSharpTests : GeneratorTestFixture } #pragma warning restore 0168 -#pragma warning restore 0219 +#pragma warning restore 0219 } [Test] @@ -81,7 +81,7 @@ public unsafe class CSharpTests : GeneratorTestFixture Assert.That(foo[0], Is.EqualTo(250)); Assert.That(foo[(uint) 0], Is.EqualTo(15)); - + var bar = new Bar(); Assert.That(bar[0].A, Is.EqualTo(10)); bar[0] = new Foo { A = 25 }; @@ -399,7 +399,7 @@ public unsafe class CSharpTests : GeneratorTestFixture Assert.AreEqual(100, p[0]); Assert.AreEqual(200, p[1]); Assert.AreEqual(300, p[2]); - + int[] array = { 1, 2, 3 }; fixed (int* p1 = array) { @@ -532,7 +532,7 @@ public unsafe class CSharpTests : GeneratorTestFixture } Assert.IsTrue(VirtualDtorAddedInDerived.DtorCalled); } - + [Test] public void TestGetEnumFromNativePointer() { @@ -722,4 +722,12 @@ public unsafe class CSharpTests : GeneratorTestFixture var i = CSharp.CSharp.UseDuplicateDeclaredStruct(duplicateDeclaredIncompleteStruct); Assert.AreEqual(10, i); } + + [Test] + public void TestMyMacroTestEnum() + { + var a = (MyMacroTestEnum)'1'; + var b = (MyMacroTestEnum)'2'; + Assert.IsTrue(a == MyMacroTestEnum.MY_MACRO_TEST_1 && b == MyMacroTestEnum.MY_MACRO_TEST_2); + } } \ No newline at end of file diff --git a/tests/CSharp/CSharp.cs b/tests/CSharp/CSharp.cs index 9ee94fc0..5a29ce17 100644 --- a/tests/CSharp/CSharp.cs +++ b/tests/CSharp/CSharp.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; using CppSharp.AST; using CppSharp.AST.Extensions; using CppSharp.Generators; @@ -33,8 +36,22 @@ namespace CppSharp.Tests ctx.SetClassAsValueType("QPoint"); ctx.SetClassAsValueType("QSize"); ctx.SetClassAsValueType("QRect"); - + ctx.SetClassAsValueType("StructTestArrayTypeFromTypedef"); ctx.IgnoreClassWithName("IgnoredTypeInheritingNonIgnoredWithNoEmptyCtor"); + + var macroRegex = new Regex(@"(MY_MACRO_TEST_.*)"); + List<string> list = new List<string>(); + foreach (TranslationUnit unit in ctx.TranslationUnits) + { + if (unit.FilePath == "<invalid>" || unit.FileName == "CSharp.h") + foreach (var macro in unit.PreprocessedEntities.OfType<MacroDefinition>()) + { + Match match = macroRegex.Match(macro.Name); + if (match.Success) list.Add(macro.Name); + } + } + var enumTest = ctx.GenerateEnumFromMacros("MyMacroTestEnum", list.ToArray()); + enumTest.Namespace = new Namespace() {Name = "MacroTest"}; } public override void Postprocess(Driver driver, ASTContext ctx) diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 5b247d57..28b1a6f7 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1169,4 +1169,13 @@ struct DLL_API ForwardDeclaredStruct { }; DLL_API ForwardDeclaredStruct* createForwardDeclaredStruct(int i); -DLL_API int useForwardDeclaredStruct(ForwardDeclaredStruct* s); \ No newline at end of file +DLL_API int useForwardDeclaredStruct(ForwardDeclaredStruct* s); + +typedef char charsArrayType[13]; +struct StructTestArrayTypeFromTypedef +{ + charsArrayType arr; +}; + +#define MY_MACRO_TEST_1 '1' +#define MY_MACRO_TEST_2 '2'