public override bool VisitClassDecl(Class @class)
 {
     // HACK: work around the bug about methods in v-tables and methods in classes not being shared objects
     foreach (VTableComponent entry in VTables.GatherVTableMethodEntries(@class))
     {
         if (entry.Method != null && (entry.Method.Name.EndsWith("Event") || entry.Method.Name == "event") &&
             entry.Method.Parameters.Count == 1 && entry.Method.Parameters[0].Type.ToString().EndsWith("Event") &&
             !entry.Method.Name.StartsWith("on"))
         {
             entry.Method.Name = "on" + char.ToUpperInvariant(entry.Method.Name[0]) + entry.Method.Name.Substring(1);
         }
     }
     return(base.VisitClassDecl(@class));
 }
示例#2
0
        public override bool VisitClassDecl(Class @class)
        {
            if (@class.IsDynamic)
            {
                // HACK: entries in v-tables are not shared (as objects) with the virtual methods they represent;
                // this is why this pass has to rename entries in the v-table as well;
                // this should be fixed in the parser: it should reuse method objects
                foreach (var method in VTables.GatherVTableMethodEntries(@class).Where(
                             e => e.Method != null && IsRenameableDecl(e.Method)).Select(e => e.Method))
                {
                    Rename(method);
                }
            }

            return(base.VisitClassDecl(@class));
        }
示例#3
0
        public override bool VisitClassDecl(Class @class)
        {
            if (@class.IsDynamic)
            {
                // HACK: entries in v-tables are not shared (as objects) with the virtual methods they represent;
                // this is why this pass fixes only the arg names used with real methods,
                // while the v-table entries could remain with empty names;
                // this should be fixed in the parser: it should reuse method objects
                foreach (var parameter in VTables.GatherVTableMethodEntries(@class).Where(
                             entry => entry.Method != null).SelectMany(entry => entry.Method.Parameters))
                {
                    parameter.Name = CheckName(parameter.Name);
                }
            }

            return(base.VisitClassDecl(@class));
        }
示例#4
0
        public override bool VisitClassDecl(Class @class)
        {
            var  originalClass = @class.OriginalClass ?? @class;
            Type returnType    = Context.ReturnType.Type.Desugar();

            // if the class is an abstract impl, use the original for the object map
            var qualifiedClass = originalClass.Visit(typePrinter);

            var   finalType = (returnType.GetFinalPointee() ?? returnType).Desugar();
            Class returnedClass;

            if (finalType.TryGetClass(out returnedClass) && returnedClass.IsDependent)
            {
                Context.Return.Write($"({returnType.Visit(typePrinter)}) (object) ");
            }

            // these two aren't the same for members of templates
            if (Context.Function?.OriginalReturnType.Type.Desugar().IsAddress() == true ||
                returnType.IsAddress())
            {
                Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass));
            }
            else
            {
                if (Context.MarshalKind == MarshalKind.NativeField ||
                    Context.MarshalKind == MarshalKind.Variable ||
                    Context.MarshalKind == MarshalKind.ReturnVariableArray ||
                    !originalClass.HasNonTrivialDestructor)
                {
                    Context.Return.Write($"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName})");
                }
                else
                {
                    Context.Before.WriteLine($@"var __{Context.ReturnVarName} = {
                        qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName});");
                    Method dtor = originalClass.Destructors.First();
                    if (dtor.IsVirtual)
                    {
                        var i           = VTables.GetVTableIndex(dtor);
                        int vtableIndex = 0;
                        if (Context.Context.ParserOptions.IsMicrosoftAbi)
                        {
                            vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.First(
                                                                             v => v.Layout.Components.Any(c => c.Method == dtor)));
                        }
                        string instance = $"new {typePrinter.IntPtrType}(&{Context.ReturnVarName})";
                        Context.Before.WriteLine($@"var __vtables = new IntPtr[] {{ {
                            string.Join(", ", originalClass.Layout.VTablePointers.Select(
                                x => $"*({typePrinter.IntPtrType}*) ({instance} + {x.Offset})"))} }};");
                        Context.Before.WriteLine($@"var __slot = *({typePrinter.IntPtrType}*) (__vtables[{
                            vtableIndex}] + {i} * sizeof({typePrinter.IntPtrType}));");
                        Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({instance}");
                        if (dtor.GatherInternalParams(Context.Context.ParserOptions.IsItaniumLikeAbi).Count > 1)
                        {
                            Context.Before.Write(", 0");
                        }
                        Context.Before.WriteLine(");");
                    }
                    else
                    {
                        string suffix         = string.Empty;
                        var    specialization = @class as ClassTemplateSpecialization;
                        if (specialization != null)
                        {
                            suffix = Helpers.GetSuffixFor(specialization);
                        }
                        Context.Before.WriteLine($@"{typePrinter.PrintNative(originalClass)}.dtor{
                            suffix}(new {typePrinter.IntPtrType}(&{Context.ReturnVarName}));");
                    }
                    Context.Return.Write($"__{Context.ReturnVarName}");
                }
            }

            return(true);
        }